Yep. I should have been more verbose about the fully qualified name part
in my first reply...

The problem with NULL VT_DISPATCH would be a bug introduced during the
COM Interop removal from Rotor. To fix it, change
OleVariant::GetVarTypeForComVariant in sscli\clr\src\vm\olevariant.cpp
to return VT_UNKNOWN instead of VT_DISPATCH (two places).

If you are playing with the FFI, you may also want to change last line
of SetupErrorInfo in clr\src\vm\interoputil.cpp to be "return E_FAIL".
This is a partial workaround for a broken error handling - InvokeByName
always returns S_OK without this fix. The next Rotor release will
include a better fix.

One more hint about how to be smart about hosting the CLR: The
managed<->unmanaged transitions are expensive and they are pain to
write. These facts are more emphasized in Rotor because of lack of the
COM Interop, but they apply for the commercial CLR too. A good CLR host
is written in the managed code as much as possible. The unmanaged part
just creates the managed host and calls the "DoIt" method on it. The
managed host can then do all the fancy stuff like create appdomains,
cache results, etc.

-Jan

This posting is provided "AS IS" with no warranties, and confers no
rights.

-----Original Message-----
From: Ted Neward [mailto:[EMAIL PROTECTED]] 
Sent: Saturday, August 03, 2002 5:19 PM
To: [EMAIL PROTECTED]
Subject: Re: [DOTNET-ROTOR] Hosting Rotor


AHA! Okay, Jan, five Duke Dollars.... uh.... Redmondian Rupees, I
mean.... to you. :-) In particular, I'm bummed because I looked at this
line four times and didn't realize what it (I think) implies:

ceemain.cpp: 592 (in ClrCreateManagedInstance):

        pClass = pDomain->FindAssemblyQualifiedTypeHandle(pName,
                                                          true,
                                                          NULL,
                                                          NULL,

&Throwable).GetClass();

I'm guessing that this is what requires a fully-qualified assembly name
to be passed in, correct?

Now for the next part--I create the managed instance successfully, now I
want to do something with it; specifically, I want to get hold of the
System.Type of the managed instance (so I can Reflect against it, and so
on). I'm doing this:

  // Create my managed instance
  //
  if (FAILED(hr =
ClrCreateManagedInstance(L"Personal.Hello,Hello,Version=1.0.0.0,Culture=
neut
ral,PublicKeyToken=2087f203b8e16004",
                                           IID_IManagedInstanceWrapper,
(void**)&pWrap)))
  {
    fprintf(stderr, "ClrCreateManagedInstance failed with hr=0x%08x\n",
hr);
    return 2;
  }

  // Try to get the type
  //
  VARIANT RetVal;
  VariantClear(&RetVal);
  if (FAILED(hr = pWrap->InvokeByName(L"GetType", CorFFIInvokeMethod, 0,
NULL, &RetVal)))
  {
      fprintf(stderr, "InvokeMethodByName failed with hr=0x%08x\n", hr);
      return 3;
  }
  // This prints out "RetVal VT=9"
  //
  printf("RetVal VT = %d\n", V_VT(&RetVal));

  // Which corresponds to VT_DISPATCH, which makes me believe I can do
this:
  //
  IManagedInstanceWrapper* pTypeWrap;
  V_UNKNOWN(&RetVal)->QueryInterface(IID_IManagedInstanceWrapper,
(void**)&pTypeWrap);
  // But I get a fatal explosion when executing this line--specifically,
V_UKNOWN(&RetVal) returns 0x00000000

  printf("pTypeWrap = %dx\n", pTypeWrap);

  VariantClear(&RetVal);
  if (FAILED(hr = pWrap->InvokeByName(L"ToString", CorFFIInvokeMethod,
0, NULL, &RetVal)))
  {
      fprintf(stderr, "InvokeMethodByName failed with hr=0x%08x\n", hr);
      return 4;
  }

  printf("RetVal VT = %d\n", V_VT(&RetVal));

So what am I getting back from the InvokeMethodByName call when the
return is a managed object type?

Ted Neward
{ .NET && Java } Author, Instructor
http://www.javageeks.com
http://www.clrgeeks.com

----- Original Message -----
From: "Jan Kotas" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Friday, August 02, 2002 5:20 PM
Subject: Re: [DOTNET-ROTOR] Hosting Rotor


> It works on non-Rotor assembly with a fully qualified name too. Here 
> is what I did:
>
>
> 1) generate a brand new strongname pair:
>
> C:\sscli\tests\dev>sn -k test.snk
>
>
> 2) create a simple assembly signed with the new key:
>
> C:\sscli\tests\dev>csc /target:library test.cs
>
> test.cs is:
> ---------------------
> using System;
> using System.Reflection;
>
> [assembly: AssemblyKeyFileAttribute("test.snk")]
> [assembly: AssemblyVersionAttribute("1.2.3.4")]
>
> namespace MyNamespace {
>     public class MyClass {
>         public MyClass() {
>         }
>
>         public int MyMethod() {
>             return 1234;
>         }
>     }
> }
> ---------------------
>
>
> 3) add the assembly to the GAC and make sure that it is there:
>
> C:\sscli\tests\dev>gacutil /i test.dll C:\sscli\tests\dev>gacutil /l 
> test
>
> The following line was somewhere in the output of the last command:
>
> test, Version=1.2.3.4, Culture=neutral, 
> PublicKeyToken=13fc20dbd9a37515, Custom=null
>
>
> 4) modify ffitest
>
> C:\sscli\tests\dev\ffitest>build
>
> The important part of ffitest.cpp is:
> -------------
>     hr = ClrCreateManagedInstance(
>
> L"MyNamespace.MyClass,test,Version=1.2.3.4,Culture=neutral,PublicKeyTo
> ke
> n=13fc20dbd9a37515",
>         IID_IManagedInstanceWrapper,
>         (void**)&pWrap);
>     if (FAILED(hr)) {
>         fprintf(stderr, "ClrCreateManagedInstance failed with
> hr=0x%08x\n", hr);
>         return 1;
>     }
>
>     VariantClear(&RetVal);
>     hr = pWrap->InvokeByName(
>         L"MyMethod", CorFFIInvokeMethod, 0, NULL, &RetVal);
>
>     if (FAILED(hr)) {
>         fprintf(stderr, "InvokeMethodByName failed with hr=0x%08x\n", 
> hr);
>         return 1;
>     }
>
>     printf("MyMethod() returned %d\n", V_I4(&RetVal));
> -------------
>
> 5) verify that it works:
>
> C:\sscli\tests\dev>ffi_test.exe
> MyMethod() returned 1234
>
> This posting is provided "AS IS" with no warranties, and confers no 
> rights.
>
> -----Original Message-----
> From: Ted Neward [mailto:[EMAIL PROTECTED]]
> Sent: Friday, August 02, 2002 4:34 PM
> To: [EMAIL PROTECTED]
> Subject: Re: [DOTNET-ROTOR] Hosting Rotor
>
>
> Jan, I would hate to be the one to disagree with you, but.... In my 
> example, Hello *was* installed in the Rotor GAC. That was the first 
> thing I thought of. Now, again, it's always possible that it's just me

> being brain-dead, but can you try the test with a non-Rotor assembly?
>
> Ted Neward
> { .NET && Java } Author, Instructor
> http://www.javageeks.com
> http://www.clrgeeks.com
>
> ----- Original Message -----
> From: "Jan Kotas" <[EMAIL PROTECTED]>
> To: <[EMAIL PROTECTED]>
> Sent: Friday, August 02, 2002 2:34 PM
> Subject: Re: [DOTNET-ROTOR] Hosting Rotor
>
>
> > The assert you are seeing is just a sideefect. It is caused by a 
> > buggy
>
> > error handling codepath in ClrCreateManagedInstance.
> >
> > The actual problem is that the fusion is not able to locate the 
> > assembly in the GAC. Unfortunately one of the limitations of the 
> > current implementation of ClrCreateManagedInstance is that it needs 
> > a fully qualified name of the assembly in order to find it in the 
> > GAC. Here is an example of a fully qualified name of an assembly 
> > that worked for me:
> >
> >     hr = ClrCreateManagedInstance(
> >
> > L"System.Xml.Xsl.XslTransform,System.Xml,Version=1.0.3300.0,Culture=
> > ne
> > ut
> > ral,PublicKeyToken=b77a5c561934e089",
> >         IID_IManagedInstanceWrapper,
> >         (void**)&pWrap);
> >
> > We will try to do better for the next Rotor release...
> >
> > -Jan
> >
> > This posting is provided "AS IS" with no warranties, and confers no 
> > rights.
> >
> > -----Original Message-----
> > From: Ted Neward [mailto:[EMAIL PROTECTED]]
> > Sent: Thursday, August 01, 2002 4:01 PM
> > To: [EMAIL PROTECTED]
> > Subject: [DOTNET-ROTOR] Hosting Rotor
> >
> >
> > I'm trying to extend and experiment with the ffi_test example, which

> > demonstrates how to create a managed instance within Rotor from 
> > unmanaged code; I've reproduced the .cpp code here[1] for reference.
> >
> > So I take the first section of code, to do the 
> > ClrCreateManagedInstance(), and I change it to do one of my own 
> > types:
> >
> >   hr = ClrCreateManagedInstance(
> >       L"Personal.Hello,Hello,PublicKeyToken=2087f203b8e16004",
> >       //L"System.Object,mscorlib,PublicKeyToken=b03f5f7f11d50a3a",
> >       //L"System.Random,mscorlib,PublicKeyToken=b03f5f7f11d50a3a",
> >       IID_IManagedInstanceWrapper,
> >       (void**)&pWrap);
> >   if (FAILED(hr)) {
> >       fprintf(stderr, "ClrCreateManagedInstance failed with 
> > hr=0x%08x\n", hr);
> >       return 2;
> >   }
> >
> > When I execute this code using the Personal.Hello type as the target

> > (where Personal.Hello is a strongly-named assembly installed in the 
> > GAC), I trip an assertion failure:
> >
> > C:\Prg\Rotor\sscli\tests\dev\host_test>rotor_x86\host.exe
> > Assert failure(PID 2296 [0x000008f8], Thread: 2308 [0x904]): 
> > !m_fPreemptiveGCDisabled
> >     File: r:\rotor\19jun2002\sscli\clr\src\vm\threads.h, Line: 899
> > Image: C:\Prg\Rotor\sscli\tests\dev\host_test\rotor_x86\host.exe
> >
> > Whereas running with the Microsoft types (System.Object or
> > System.Random) offers up no such assertion. Anybody got any ideas 
> > what's going on here, or what I'm doing wrong? (I'm hoping this is a

> > quick-answer--I've not dug into the ClrCreateInstance impl to try 
> > and debug it.)
> >
> > Ted Neward
> > {.NET || Java} Course Author & Instructor, DevelopMentor
> > (http://www.develop.com)
> > http://www.javageeks.com/tneward http://www.clrgeeks.com/tneward
> >
> > [1] from sscli/tests/dev/ffi_test/ffitest.cpp
> >
> > #include "windows.h"
> > #include "stdlib.h"
> >
> > #include "cor.h"
> > #include "mscoree.h"
> > #include "corffi.h"
> >
> > int __cdecl main(int argc, char ** argv, char ** envp)
> > {
> >     IManagedInstanceWrapper *pWrap;
> >     VARIANT RetVal;
> >     HRESULT hr;
> >
> >     if (!PAL_RegisterLibrary(L"rotor_palrt") ||
> >         !PAL_RegisterLibrary(L"sscoree")) {
> >         fprintf(stderr, "PAL_RegisterLibraryW failed\n");
> >         return 1;
> >     }
> >
> >     hr = ClrCreateManagedInstance(
> >         L"System.Random,mscorlib,PublicKeyToken=b03f5f7f11d50a3a",
> >         IID_IManagedInstanceWrapper,
> >         (void**)&pWrap);
> >     if (FAILED(hr)) {
> >         fprintf(stderr, "ClrCreateManagedInstance failed with 
> > hr=0x%08x\n", hr);
> >         return 2;
> >     }
> >
> >     VariantClear(&RetVal);
> >     hr = pWrap->InvokeByName(
> >         L"Next", CorFFIInvokeMethod, 0, NULL, &RetVal);
> >
> >     if (FAILED(hr)) {
> >         fprintf(stderr, "InvokeMethodByName failed with 
> > hr=0x%08x\n", hr);
> >         return 3;
> >     }
> >
> >     if (V_VT(&RetVal) != VT_I4) {
> >         fprintf(stderr, "Invalid return type (%d)\n",
V_VT(&RetVal));
> >         return 3;
> >     }
> >
> >     printf("System.Random.Next() returned %d\n", V_I4(&RetVal));
> >
> >     pWrap->Release();
> >
> >     return 0;
> > }
> >
>

Reply via email to