当前位置: 首页 > 编程语言 > C#

如何在C#应用程序中使用DllExportC++类Share

时间:2023-04-11 11:23:23 C#

如何在C#应用程序中使用DllExportC++类//msdn.microsoft.com/en-us/library/a90k134d(v=vs.80)of.aspxclass__declspec(dllexport)CExampleExport://publicCObject{...类定义...};我省略了“publicCObject”,因为它需要afx.h并暗示它是一个MFCDll。我不确定这是否是一件好事,但它与DLL项目默认设置不同。从上面链接的文档我可以相信所有“公共函数和成员变量”都可以导入。我怎样才能在C#中实现这一点?类可以简单实例化吗?编辑:我刚刚意识到帖子的标题可能具有误导性。重点应该放在从C#导入Dll上,并确保我在C++中正确地遵循了文档C#不能直接导入C++类(实际上是错误命名的C接口)。您可以选择通过COM公开类,使用C++/CLI创建托管包装器,或公开C风格的接口。我建议使用托管包装器,因为这是最简单的并且提供最好的类型安全性。C风格的界面看起来像这样(警告:未经测试的代码):}extern"C"__declspec(dllexport)intCExampleExport_ReadValue(void*this,intparam){return((CExampleExport*)this)->ReadValue(param)}C++/CLI风格的包装看起来像这样(警告:未经测试代码):refclassExampleExport{private:CExampleExport*impl;public:ExampleExport(intparam1,doubleparam2){impl=newCExampleExport(param1,param2);}intReadValue(intparam){returnimpl->ReadValue(param);}~ExampleExport(){删除实现;}};据我所知,C#只能与COM接口进行互操作。幸运的是,它不需要是带有注册表的完整COM对象,它可以是任何实现IUnknown的普通旧C++类。所以在C++中做这样的事情:#include//GeneratewithfromVisualStudioTools/CreateGuidmenustaticconstGUIDIID_MyInterface={0xefbf7d84,0x3efe,0x41e0,{0x95,0x2e,0x68,0xa4,0x4a,0x3e,0x72,0xca}};structMyInterface:publicIUnknown{//在这里添加你自己的函数//它们应该是虚拟的并且__stdcallSTDMETHOD_(double,GetValue)()=0;标准方法(抛出错误)()=0;};类MyClass:publicMyInterface{volatilelongrefcount_;public:MyClass():refcount_(1){}STDMETHODIMPQueryInterface(REFIIDguid,void**pObj){if(pObj==NULL){returnE_POINTER;}elseif(guid==IID_IUnknown){*pObj=this;添加参考();返回S_OK;}elseif(guid==IID_MyInterface){*pObj=this;添加参考();返回S_OK;}else{//总是设置[out]参数*pObj=NULL;返回E_NOINTERFACE;}}STDMETHODIMP_(ULONG)AddRef(){返回InterlockedIncrement(&refcount_);}STDMETHODIMP_(ULONG)Release(){ULONG结果=InterlockedDecrement(&refcount_);如果(结果==0)删除这个;返回结果;}STDMETHODIMP_(DOUBLE)GetValue(){返回42.0;}STDMETHODIMPThrowError(){返回E_FAIL;}};extern"C"__declspec(dllexport)LPUNKNOWNWINAPICreateInstance(){returnnewMyClass();在C#端,您可以执行以下操作:空投掷错误();}classProgram{[DllImport("mylib.dll")]staticexternMyInterfaceCreateInstance();staticvoidMain(string[]args){MyInterfaceiface=CreateInstance();Console.WriteLine(iface.GetValue());尝试{iface.ThrowError();}catch(Exceptionex){Console.WriteLine(ex);}Console.ReadKey(true);只有C++C#和C#之间的通信是通过虚拟接口,你可以用这种方式做任何你想做的事你不能在C#中通过pinvoke创建C++类实例。这是一个讨厌的实现细节,只有C++编译器知道需要分配多少内存以及何时以及如何正确调用构造函数和析构函数。目标尺寸是迄今为止最难破解的螺母,没有办法使其可靠。如果不能将C++类压缩为静态方法,则需要编写托管包装器。这是用C++/CLI语言完成的,您编写一个“ref类”,它将非托管类对象存储为指针,在构造函数中创建并在析构函数和终结器中删除。实际上,您可以使用DllImport属性的EntryPoint属性直接引用经过修饰的名称。有关详细信息,请参阅此答案。C#和C++不像C++和Delphi那样是ABI兼容的,所以你不能导出虚拟类成员(方法)并在调用它们时将它们声明为纯粹调用它们,因为C#无法处理vtbl的C+++对象。我建议你用COM包装你的C++类,这样你会有另一个积极的副作用,其他COM兼容语言也可以使用你的类。以上就是C#学习教程分享的全部内容:如何在C#应用程序中使用DllExportC++类。如果对你有用,需要了解更多C#学习教程,希望大家多加关注——本文来自网络收集,不代表立场,如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢