简体   繁体   中英

Using a Very C# DLL in C++

I am trying to use a C# DLL which has multiple references to .NET classes and C# Classes in Embarcadero C++ Builder. Things like the Point class and String class as well as Delegates.

I am wondering if the >NET references or C# ones will mess me up somehow. I am just about to getting it hooked up, but I am wondering if some of the problems I am having could be caused by C++ not wanting to play nice.

I gave a similar answer to your problem in this question .

You basically want a C++/CLI interface to your C# code.

If you want to pass a C# delegate to C++ code, you can translate it using Marshal::GetFunctionPointerForDelegate() ( MSDN ). That gives you a IntPtr that you can call ToPointer() on to pass in as a function pointer.

You will need to use C++/CLI to use any .NET content in C++. You might also be able to set up your own AppDomain, but those are the only two choices, as C++ has no native ability to interact with .NET, at all.

Or you can use the mono CLR embedder

Managed code can invoke unmanaged code in two ways, [using P/Invoke or] using the low-level Mono embedding API .

This works a lot like the oldfashioned embedding of a Perl, Python or Ruby 'interpreter' (actually, virtual machines) in your C/C++ executable. I don't think there is actually such a thing as a Swig(++) wrapper generator for this (yet), but here is a snippet of what a call into CIL code looks like:

 class MyClass {
    static void Foo (int value) {
      ...
    }

    int Bar (string name) {
      ...
    }
  }

assuming you got the corresponding MonoMethod* in foo_method and bar_method and this_arg is a MonoObject* of type MyClass, you simply execute:

  /* we execute methods that take one argument */
  void *args [1];
  int val = 10;
  /* Note we put the address of the value type in the args array */
  args [0] = &val;

  /* execute Foo (10);
   * it's a static method, so use NULL as the second argument.
   */
  mono_runtime_invoke (foo_method, NULL, args, NULL);

  /* a string is a reference, so we put it directly in the args array */
  args [0] = mono_string_new (domain, "Hello");
  /* execute my_class_instance.Bar ("Hello");
   * See the Creating Objects section to learn how to get this_arg.
   */
  MonoObject *result = mono_runtime_invoke (bar_method, this_arg, args, NULL);
  /* we always get a MonoObject* from mono_runtime_invoke (), so to get
   * the integer value we need to unbox (which returns a pointer to
   * the value stored in the object) and dereference.
   */
  int int_result = *(int*)mono_object_unbox (result);

For extra entertainment value : if you AOT-compile all of your CIL code, you'll be able to statically link your assembly into your native binary (effectively doing what Managed C++ (c++-cli) calls mixed mode assemblies). Look at

 mono --aot=static myassembly.dll

and

 mkbundle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM