Создайте неуправляемый объект С++ в С#
У меня есть неуправляемая dll с классом MyClass.
Теперь есть способ создать экземпляр этого класса в коде С#? Вызов его конструктора? Я попытался, но визуальная студия сообщила об ошибке с сообщением о том, что эта область памяти повреждена или что-то в этом роде.
Заранее спасибо
Ответы
Ответ 1
С# не может создать экземпляр класса, экспортированного из родной Dll. У вас есть два варианта:
-
Создайте оболочку С++/CLI. Это библиотека классов .NET, которая может быть добавлена как ссылка на любой другой проект .NET. Внутренний класс С++/CLI работает с неуправляемым классом, привязывая к родной Dll стандартными правилами С++. Для .NET-клиента этот класс С++/CLI выглядит как класс .NET.
-
Write C wrapper для класса С++, который может использоваться клиентом .NET с PInvoke. Например, чрезмерно упрощенный класс С++:
class MyClass()
{
public:
MyClass(int n){data=n;}
~MyClass(){}
int GetData(){return data;}
private:
int data;
};
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 могут быть объявлены в клиенте С# с использованием PInvoke и вызваны напрямую. Параметр void * должен быть объявлен как IntPtr в объявлении PInvoke.
Ответ 2
Вы не можете использовать код С++ без изменений непосредственно на С#. Взаимодействие можно выполнить с помощью PInvoke. Есть много проблем, связанных с этим темой, особенно при вызове функций, которые имеют указатели в качестве аргументов.
Основная процедура выполняется следующим образом:
С# часть
namespace MyNamespace {
public class Test {
[DllImport("TheNameOfThe.dll")]
public static extern void CreateMyClassInstance();
public void CallIt() {
CreateMyClassInstance(); // calls the unmanged function via PInvoke
}
}
}
Часть С++
class MyClass {
public: MyClass() { /** Constructor */ }
};
MyClass* staticObject;
extern "C" void CreateMyObjectInstance() {
staticObject = new MyClass(); // constructor is called
}
Ответ 3
Решение представляет собой оболочку С++/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 - это класс, экспортированный из собственного кода. Выше находится .h С++/CLI. Позаботьтесь, чтобы найти lib для этой DLL. Поместите dll и lib в тот же каталог и скомпилируйте код С++/CLI. В каталоге управляемого кода поместите собственную dll и DLL С++/CLI. В управляемом проекте укажите ссылку на проект С++/CLI. Исключить в обработанном коде класс С++/CLI:
ManagedOperationHelper obj = new ManagedOperationHelper();
double ret=obj.Sum(10, 20);
Все.