C# 如何从 C/C++ 调用 .NET 程序集?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/106033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I call a .NET assembly from C/C++?
提问by cwick
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# 类的属性?
采纳答案by Francis B.
[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 组件。
回答by QBziZ
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 调用它。
回答by Jason Dagit
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 blogto get some concrete details.
您可以查看此博客以获取一些具体细节。
回答by rp.
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) 标记该类,并确保将程序集信息 SetAssemblyAtribute 设置为 ComVisible(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.tbl /codebase 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
转速
回答by Wayne Bloss
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
(a) 使用 COM-Interop
(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++ 应用程序:MC++ 和 IJW 应用程序可以相互调用。
(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 可以由非托管应用程序托管,这意味着运行时会调用一堆托管回调。
回答by Hallgrim
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++ 代码调用(高级)实现。
回答by Kevin
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 包装器。
回答by cwick
I found this link to embedding Mono: http://www.mono-project.com/Embedding_Mono
我找到了嵌入 Mono 的链接:http: //www.mono-project.com/Embedding_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
它提供了一个看起来非常简单的界面来与程序集交互。这可能是一个有吸引力的选择,特别是如果您想跨平台
回答by Rob Walker
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 unmanagedcode will be architecture specific. You will need separates builds for x86 and x64 (and IA64).
需要注意的另一件事是,包含非托管代码的C++/CLI 程序集将是特定于体系结构的。您将需要为 x86 和 x64(以及 IA64)单独构建。