如何从C/ c++调用。net程序集?

时间:2022-09-01 16:36:39

Suppose I am writing an application in C++ and C#. I want to write the low level parts in C++ and write the high level logic in C#. How can I load a .NET assembly from my C++ program and start calling methods and accessing the properties of my C# classes?

假设我正在用c++和c#编写一个应用程序。我想用c++编写低级别的部分,并在c#中编写高级逻辑。如何从c++程序加载.NET程序集并开始调用方法并访问c#类的属性?

9 个解决方案

#1


12  

[Guid("123565C4-C5FA-4512-A560-1D47F9FDFA20")]
public interface IConfig
{
    [DispId(1)]
    string Destination{ get; }

    [DispId(2)]
    void Unserialize();

    [DispId(3)]
    void Serialize();
}

[ComVisible(true)]
[Guid("12AC8095-BD27-4de8-A30B-991940666927")]
[ClassInterface(ClassInterfaceType.None)]
public sealed class Config : IConfig
{
    public Config()
    {
    }

    public string Destination
    {
        get { return ""; }
    }

    public void Serialize()
    {
    }

    public void Unserialize()
    {
    }
}

After that, you need to regasm your assembly. Regasm will add the necessary registry entries to allow your .NET component to be see as a COM Component. After, you can call your .NET Component in C++ in the same way as any other COM component.

之后,您需要重新生成程序集。Regasm将添加必要的注册表项,以允许将. net组件视为COM组件。之后,您可以像调用其他COM组件一样在c++中调用。net组件。

#2


13  

You should really look into C++/CLI. It makes tasks like this nearly trivial.

您应该认真研究c++ /CLI。它使这样的任务变得几乎微不足道。

Otherwise, you'll have to generate COM wrappers around the C# code and have your C++ app call the COM wrappers.

否则,您将不得不在c#代码周围生成COM包装,并让您的c++应用程序调用COM包装器。

#3


4  

I would definitely investigate C++/CLI for this and avoid COM and all the registration hassles that tends to produce.

我肯定会为此调查c++ /CLI,避免COM和所有容易产生的注册麻烦。

What is the motivation for using C++? If it is simply style then you might find you can write everything in C++/CLI. If it is performance then calling back and forth between managed C++ and unmanaged code is relatively straight forward. But it is never going to be transparent. You can't pass a managed pointer to unmanaged code first without pinning it so that the garbage collector won't move it, and of course unmanaged code won't know about your managed types. But managed (C++) code can know about your unmanaged types.

使用c++的动机是什么?如果它是简单的样式,那么您可能会发现您可以在c++ /CLI中编写所有内容。如果是性能,那么在托管c++和非托管代码之间来回调用是相对直接的。但它永远不会是透明的。如果不将托管指针固定到非托管代码,那么垃圾收集器就不会移动它,当然,非托管代码也不会知道托管类型。但是托管(c++)代码可以了解非托管类型。

One other thing to note is that C++/CLI assemblies that include unmanaged code will be architecture specific. You will need separates builds for x86 and x64 (and IA64).

另外需要注意的一点是,包含非托管代码的c++ /CLI程序集将是特定于体系结构的。您将需要为x86和x64(和IA64)分别构建版本。

#4


0  

You can wrap the .NET component in a COM component - which is quite easy with the .NET tools - and call it via COM.

您可以将. net组件封装到COM组件中——这在. net工具中非常简单——并通过COM调用它。

#5


0  

If the low level parts in in C++ then typically you call that from the C# code passing in the values that are needed. This should work in the standard way that you're probably accustomed to. You'll need to read up on marshalling for example.

如果在c++中较低的部分,那么您通常会调用从需要的值中传递的c#代码。这应该以您可能已经习惯的标准方式工作。例如,您需要阅读有关封送的内容。

You could look at this blog to get some concrete details.

你可以看看这个博客来获得一些具体的细节。

#6


0  

Create your .NET assembly as normal, but be sure to mark the class with the ClassInterface(ClassInterfaceType.AutoDual) and be sure an assembly info SetAssemblyAtribute to ComVisible( true ).

按照正常的方式创建. net程序集,但是一定要用ClassInterface(ClassInterfaceType.AutoDual)来标记这个类,并且要确保一个程序集信息setassembly yatribute可以显示(true)。

Then, create the COM wrapper with REGASM:

然后用REGASM创建COM包装器:

regasm mydll.dll /tlb:mydll.tbl /codebase f:_code\ClassLibraryForCom

regasm mydll。dll / tlb:mydll。台/代码库f:_code \ ClassLibraryForCom

be sure to use the /codebase directive -- it is necessary if you aren't going to give the assembly a strong name.

一定要使用/codebase指令——如果不给程序集一个强名称的话,这是必要的。

rp

rp

#7


0  

Since C# can import C++ standard exports, it might be easier to load up your C++ dll inside of a C# application instead of using COM from C++.

因为c#可以导入c++标准导出,所以在c#应用程序中加载c++ dll可能比在c++中使用COM更容易。

See documentation for System.Runtime.InteropServices.DllImport.

看到System.Runtime.InteropServices.DllImport文档。

Also, here is a complete list of the types of Interop that you can do between managed and unmanaged code:

另外,这里列出了托管和非托管代码之间可以进行的互操作类型的完整列表:

http://blogs.msdn.com/deeptanshuv/archive/2005/06/26/432870.aspx

http://blogs.msdn.com/deeptanshuv/archive/2005/06/26/432870.aspx

In a nutshell:

简而言之:

(a) Using COM-Interop

使用COM-Interop(a)

(b) Using imports/pinvoke (explicit method calls)

(b)使用导入/pinvoke(显式方法调用)

(c) IJW and MC++ apps : MC++ & IJW apps can freely call back and forth to each other.

(c) IJW和MC++ + apps: MC++ & IJW apps可以*的相互调用。

(d) Hosting. This is rare, but the CLR can be hosted by an unmanaged app which means that the runtime invokes a bunch of hosting callbacks.

(d)托管。这是很少见的,但是CLR可以由一个非托管的应用程序托管,这意味着运行时将调用一系列托管回调。

#8


0  

If you can have both managed and unmanaged code in your process, you can create a C++ class with virtual functions. Implement the class with mixed mode C++/CLI. Inject the implementation to your C++ code, so that the (high-level) implementation can be called from your (low-level) C++ code.

如果您可以在您的进程中同时拥有托管和非托管代码,那么您可以创建一个带有虚拟函数的c++类。使用混合模式c++ /CLI实现该类。将实现注入您的c++代码,以便从您的(低级)c++代码调用(高级)实现。

#9


0  

I found this link to embedding Mono: http://www.mono-project.com/Embedding_Mono

我找到了嵌入Mono的链接:http://www.mono- project.com/embed _embed _mono

It provides what seems to be a pretty straightforward interface for interacting with assemblies. This could be an attractive option, especially if you want to be cross-platform

它为与程序集交互提供了一个非常简单的接口。这可能是一个很有吸引力的选择,特别是如果你想跨平台的话

#1


12  

[Guid("123565C4-C5FA-4512-A560-1D47F9FDFA20")]
public interface IConfig
{
    [DispId(1)]
    string Destination{ get; }

    [DispId(2)]
    void Unserialize();

    [DispId(3)]
    void Serialize();
}

[ComVisible(true)]
[Guid("12AC8095-BD27-4de8-A30B-991940666927")]
[ClassInterface(ClassInterfaceType.None)]
public sealed class Config : IConfig
{
    public Config()
    {
    }

    public string Destination
    {
        get { return ""; }
    }

    public void Serialize()
    {
    }

    public void Unserialize()
    {
    }
}

After that, you need to regasm your assembly. Regasm will add the necessary registry entries to allow your .NET component to be see as a COM Component. After, you can call your .NET Component in C++ in the same way as any other COM component.

之后,您需要重新生成程序集。Regasm将添加必要的注册表项,以允许将. net组件视为COM组件。之后,您可以像调用其他COM组件一样在c++中调用。net组件。

#2


13  

You should really look into C++/CLI. It makes tasks like this nearly trivial.

您应该认真研究c++ /CLI。它使这样的任务变得几乎微不足道。

Otherwise, you'll have to generate COM wrappers around the C# code and have your C++ app call the COM wrappers.

否则,您将不得不在c#代码周围生成COM包装,并让您的c++应用程序调用COM包装器。

#3


4  

I would definitely investigate C++/CLI for this and avoid COM and all the registration hassles that tends to produce.

我肯定会为此调查c++ /CLI,避免COM和所有容易产生的注册麻烦。

What is the motivation for using C++? If it is simply style then you might find you can write everything in C++/CLI. If it is performance then calling back and forth between managed C++ and unmanaged code is relatively straight forward. But it is never going to be transparent. You can't pass a managed pointer to unmanaged code first without pinning it so that the garbage collector won't move it, and of course unmanaged code won't know about your managed types. But managed (C++) code can know about your unmanaged types.

使用c++的动机是什么?如果它是简单的样式,那么您可能会发现您可以在c++ /CLI中编写所有内容。如果是性能,那么在托管c++和非托管代码之间来回调用是相对直接的。但它永远不会是透明的。如果不将托管指针固定到非托管代码,那么垃圾收集器就不会移动它,当然,非托管代码也不会知道托管类型。但是托管(c++)代码可以了解非托管类型。

One other thing to note is that C++/CLI assemblies that include unmanaged code will be architecture specific. You will need separates builds for x86 and x64 (and IA64).

另外需要注意的一点是,包含非托管代码的c++ /CLI程序集将是特定于体系结构的。您将需要为x86和x64(和IA64)分别构建版本。

#4


0  

You can wrap the .NET component in a COM component - which is quite easy with the .NET tools - and call it via COM.

您可以将. net组件封装到COM组件中——这在. net工具中非常简单——并通过COM调用它。

#5


0  

If the low level parts in in C++ then typically you call that from the C# code passing in the values that are needed. This should work in the standard way that you're probably accustomed to. You'll need to read up on marshalling for example.

如果在c++中较低的部分,那么您通常会调用从需要的值中传递的c#代码。这应该以您可能已经习惯的标准方式工作。例如,您需要阅读有关封送的内容。

You could look at this blog to get some concrete details.

你可以看看这个博客来获得一些具体的细节。

#6


0  

Create your .NET assembly as normal, but be sure to mark the class with the ClassInterface(ClassInterfaceType.AutoDual) and be sure an assembly info SetAssemblyAtribute to ComVisible( true ).

按照正常的方式创建. net程序集,但是一定要用ClassInterface(ClassInterfaceType.AutoDual)来标记这个类,并且要确保一个程序集信息setassembly yatribute可以显示(true)。

Then, create the COM wrapper with REGASM:

然后用REGASM创建COM包装器:

regasm mydll.dll /tlb:mydll.tbl /codebase f:_code\ClassLibraryForCom

regasm mydll。dll / tlb:mydll。台/代码库f:_code \ ClassLibraryForCom

be sure to use the /codebase directive -- it is necessary if you aren't going to give the assembly a strong name.

一定要使用/codebase指令——如果不给程序集一个强名称的话,这是必要的。

rp

rp

#7


0  

Since C# can import C++ standard exports, it might be easier to load up your C++ dll inside of a C# application instead of using COM from C++.

因为c#可以导入c++标准导出,所以在c#应用程序中加载c++ dll可能比在c++中使用COM更容易。

See documentation for System.Runtime.InteropServices.DllImport.

看到System.Runtime.InteropServices.DllImport文档。

Also, here is a complete list of the types of Interop that you can do between managed and unmanaged code:

另外,这里列出了托管和非托管代码之间可以进行的互操作类型的完整列表:

http://blogs.msdn.com/deeptanshuv/archive/2005/06/26/432870.aspx

http://blogs.msdn.com/deeptanshuv/archive/2005/06/26/432870.aspx

In a nutshell:

简而言之:

(a) Using COM-Interop

使用COM-Interop(a)

(b) Using imports/pinvoke (explicit method calls)

(b)使用导入/pinvoke(显式方法调用)

(c) IJW and MC++ apps : MC++ & IJW apps can freely call back and forth to each other.

(c) IJW和MC++ + apps: MC++ & IJW apps可以*的相互调用。

(d) Hosting. This is rare, but the CLR can be hosted by an unmanaged app which means that the runtime invokes a bunch of hosting callbacks.

(d)托管。这是很少见的,但是CLR可以由一个非托管的应用程序托管,这意味着运行时将调用一系列托管回调。

#8


0  

If you can have both managed and unmanaged code in your process, you can create a C++ class with virtual functions. Implement the class with mixed mode C++/CLI. Inject the implementation to your C++ code, so that the (high-level) implementation can be called from your (low-level) C++ code.

如果您可以在您的进程中同时拥有托管和非托管代码,那么您可以创建一个带有虚拟函数的c++类。使用混合模式c++ /CLI实现该类。将实现注入您的c++代码,以便从您的(低级)c++代码调用(高级)实现。

#9


0  

I found this link to embedding Mono: http://www.mono-project.com/Embedding_Mono

我找到了嵌入Mono的链接:http://www.mono- project.com/embed _embed _mono

It provides what seems to be a pretty straightforward interface for interacting with assemblies. This could be an attractive option, especially if you want to be cross-platform

它为与程序集交互提供了一个非常简单的接口。这可能是一个很有吸引力的选择,特别是如果你想跨平台的话