Moving from Module Builder to Type Builder

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Marek

    #1

    Moving from Module Builder to Type Builder

    Hi
    I need to call various functions in a native C++ DLL (FORTRAN eventually
    too) - passing integers, doubles, (pointers and arrays to both of these as
    well) and ultimately structures too. I was quite happily proceeding using
    ModuleBuilder.D efinePInvokeMet hod until I started implementing calls to
    pointer (byref) parameters. The switch to TypeBuilder.Def inePInvokeMetho d
    (the one with the required custom modifiers) has resulted in the message
    "the invoked member is not supported in a dynamic module".

    Please could someone step me through the required calls in order to create a
    totally dynamic call to such a DLL using the above approach. I don't really
    want to save temporary assemblies to disk, but will if that is what it
    required.

    The sample below shows the module builder approach (which works) and then
    the switch to the type builder approach which I am having problems with
    (note: uses simple form of the method). The C++ function being called is
    declared as follows:

    extern "C"
    {
    __declspec( dllexport ) double WINAPI AddTwoDoubles2( double a, double b)
    {
    return a+b;

    }
    }
    Thanks for any help anyone can provide.

    Marek

    C# code using module builder follows (this works
    fine)********** *************** *************** ***
    Type returnType = typeof(double);

    //...Set up the parameters:
    Type[] parameterTypes = new Type[2];
    object[] parameterValues = new object[2];

    parameterTypes[0] = typeof(double);
    parameterValues[0] = 2;

    parameterTypes[1] = typeof(double);
    parameterValues[1] = 2;

    // Create a dynamic assembly and a dynamic module
    AssemblyName assemblyName = new AssemblyName();
    assemblyName.Na me = "tempDll";
    AssemblyBuilder assemblyBuilder =
    AppDomain.Curre ntDomain.Define DynamicAssembly (assemblyName,
    AssemblyBuilder Access.Run);
    ModuleBuilder moduleBuilder =
    assemblyBuilder .DefineDynamicM odule("tempModu le");

    // Dynamically construct a global PInvoke signature using the
    input information
    MethodBuilder methodBuilder =
    moduleBuilder.D efinePInvokeMet hod(entryPointN ame,

    dllName,

    MethodAttribute s.Static | MethodAttribute s.Public |
    MethodAttribute s.PinvokeImpl,

    CallingConventi ons.Standard,

    returnType,

    parameterTypes,

    CallingConventi on.Winapi,

    CharSet.Ansi);

    // This global method is now complete

    methodBuilder.S etImplementatio nFlags(MethodIm plAttributes.Pr eserveSig);
    moduleBuilder.C reateGlobalFunc tions();

    // Get a MethodInfo for the PInvoke method
    MethodInfo methodInfo = moduleBuilder.G etMethod(entryP ointName);

    Object returnValue = new Object();

    try
    {
    returnValue = methodInfo.Invo ke(null, parameterValues );
    MessageBox.Show (String.Format( "Value calculated: {0}",
    Convert.ToDoubl e(returnValue). ToString()), entryPointName) ;
    }
    catch (Exception ex)
    {
    MessageBox.Show (ex.Message, entryPointName) ;

    if (ex.InnerExcept ion != null)
    MessageBox.Show (ex.InnerExcept ion.Message);
    }

    C# code using type builder follows (this doesn't
    work)********** *************** *************** ***

    AssemblyName assemblyName = new AssemblyName();
    assemblyName.Na me = "tempDll";
    AssemblyBuilder assemblyBuilder =
    AppDomain.Curre ntDomain.Define DynamicAssembly (assemblyName,
    AssemblyBuilder Access.Run);
    ModuleBuilder moduleBuilder =
    assemblyBuilder .DefineDynamicM odule("tempModu le");

    // Dynamically construct a global PInvoke signature using the
    input information
    TypeBuilder typeBuilder = moduleBuilder.D efineType("Temp Type");
    MethodBuilder methodBuilder =
    typeBuilder.Def inePInvokeMetho d(entryPointNam e,

    dllName,

    MethodAttribute s.Static | MethodAttribute s.Public |
    MethodAttribute s.PinvokeImpl,

    CallingConventi ons.Standard,

    returnType,

    parameterTypes,

    CallingConventi on.Winapi,

    CharSet.Ansi);

    // This global method is now complete

    methodBuilder.S etImplementatio nFlags(MethodIm plAttributes.Pr eserveSig);
    moduleBuilder.C reateGlobalFunc tions();

    //...GetMethod returns nothing
    MethodInfo methodInfo = moduleBuilder.G etMethod(entryP ointName);

    Object returnValue = new Object();

    try
    {
    // Calling method builder directly results in the exception
    "The invoked member is not supported in a dynamic module"
    returnValue = methodBuilder.I nvoke(null, parameterValues );

Working...