C# 在C中创建非托管C++对象

C# 在C中创建非托管C++对象,c#,.net,c++,unmanaged,C#,.net,C++,Unmanaged,我有一个非托管dll,其中有一个类MyClass。 现在有没有办法用C代码创建这个类的实例?调用它的构造函数?我尝试过,但VisualStudio报告了一个错误,并显示一条消息,表示该内存区域已损坏或有问题 提前感谢C无法创建从本机Dll导出的类实例。您有两个选择: 创建C++/CLI包装器。这是一个.NET类库,可以添加为对任何其他.NET项目的引用。在内部,C++/CLI类与非托管类一起工作,通过标准C++规则链接到本地Dll。对于.NET客户端,此C++/CLI类类似于.NET类 为C++

我有一个非托管dll,其中有一个类MyClass。 现在有没有办法用C代码创建这个类的实例?调用它的构造函数?我尝试过,但VisualStudio报告了一个错误,并显示一条消息,表示该内存区域已损坏或有问题


提前感谢

C无法创建从本机Dll导出的类实例。您有两个选择:

创建C++/CLI包装器。这是一个.NET类库,可以添加为对任何其他.NET项目的引用。在内部,C++/CLI类与非托管类一起工作,通过标准C++规则链接到本地Dll。对于.NET客户端,此C++/CLI类类似于.NET类

为C++类编写C包装器,可以使用PInvoke的.NET客户端使用。例如,过于简化的C++类:

此类的C API包装器:

void* CreateInstance() { MyClass* p = new MyClass(); return p; } void ReleaseInstance(void* pInstance) { MyClass* p = (MyClass*)pInstance; delete p; } int GetData(void* pInstance) { MyClass* p = (MyClass*)pInstance; return p->GetData(); } // Write wrapper function for every MyClass public method. // First parameter of every wrapper function should be class instance.
CreateInstance、ReleaseInstance和GetData可以在C客户机中使用PInvoke声明,并直接调用。PUTKEY声明中的参数应该声明为ItpTR。

< P>不能直接使用C中的未处理的C++代码。有,特别是在调用以指针作为参数的函数时

基本程序如下:

C部分

C++部分


解决方案是创建C++/CLI包装器,类似于:

#include "DllExportClass.h"

public ref class ManagedOperationHelper
{
    public:

    double Sum(double add1, double add2)
    {
        CDllExportClass obj;
        double ret=obj.Sum(add1, add2);
        return ret;
    }

    double Mult(double mult1, double mult2)
    {
        CDllExportClass obj;
        double ret=obj.Mult(mult1, mult2);
        return ret;
    }
};
其中CDllExportClass是从本机代码导出的类。上面是C++/CLI的.h。注意让我们找到这个dll的库。将dll和lib放在同一目录中,并编译C++/CLI代码。在托管代码目录中放置本机dll和C++/CLI dll。在托管项目中放置C++/CLI项目的引用。在损坏的代码中实例化C++/CLI类,如:

ManagedOperationHelper obj = new ManagedOperationHelper();
double ret=obj.Sum(10, 20);  

就这些。

1静态无效主字符串[]args{IntPtr p=new IntPtr;Program.CreateObservref p;}[DllImport@C:\mm_2008\liba.dll,入口点=??0CRls@fld@@QAE@ABV01@@Z、 SetLastError=true,CallingConvention=CallingConvention.ThisCall]内部静态外部无效CreateObservref IntPtr p;此代码引发AccessViolationException:AccessViolationException尝试读取或写入受保护的内存…2静态无效主字符串[]args{IntPtr p=Program.CreateObserv;}[DllImport@C:\mm_2008\liba.dll,入口点=??0CRls@fld@@QAE@ABV01@@Z、 SetLastError=true,allingConvention=CallingConvention.ThisCall]内部静态外部IntPtr CreateObserv;-此代码会压碎应用程序和应用程序主机,以避免诸如??0CRls@fld@@QAE@ABV01@@Z、 在非托管Dll中使用外部C。声明为ExtnC的函数是没有名字的导出。@ EvGyy0.7不要在注释中添加代码,删除注释并将代码放入问题中。谢谢大家,我不承认,但除了写包装外,没有别的方法。其他的选择是使用Cyp/CRL标志编写托管C++。然后可以在同一dll中混合使用非托管代码和托管代码,然后在C代码中简单地调用托管方法。它将生成SAMIL代码,就像您在代码中包装本机方法一样。快速介绍您在包装函数中错过了一个外部C。Danvil-这是我在问题说明中写的。不管怎样,谢谢,我现在感觉好多了。亚历克斯,如果在C++的本地DLL中有一个类的层次,那又是什么?什么使它成为一个C API?不是新的和删除C++构造吗?好像只是一个静态C++API@Rotem我的意思是,这个包装器是可用于C客户端,以及任何客户端与C风格的API:.NET PInvoke,组装,Delphi等包装器本身是在C++实现。
class MyClass {
  public: MyClass() { /** Constructor */ }
};

MyClass* staticObject;

extern "C" void CreateMyObjectInstance() {
   staticObject = new MyClass(); // constructor is called
} 
#include "DllExportClass.h"

public ref class ManagedOperationHelper
{
    public:

    double Sum(double add1, double add2)
    {
        CDllExportClass obj;
        double ret=obj.Sum(add1, add2);
        return ret;
    }

    double Mult(double mult1, double mult2)
    {
        CDllExportClass obj;
        double ret=obj.Mult(mult1, mult2);
        return ret;
    }
};
ManagedOperationHelper obj = new ManagedOperationHelper();
double ret=obj.Sum(10, 20);