我有一个C ++ DLL,其中导出了以下函数。
double getDouble(std::wstring filename, std::string ID, status &stCode);
int getInt(std::wstring filename, std::string ID, status &stCode);
float getFloat(std::wstring filename, std::string ID, status &stCode);
string getString(std::wstring filename, std::string ID, status &stCode);
int* getIntArray(std::wstring filename, std::string ID, status &stCode);
float* getFloatArray(std::wstring filename, std::string ID, status &stCode);
string* getStringArray(std::wstring filename, std::string ID, status &stCode);
其中状态为枚举类型...
现在我想在我的C#.NET应用程序中使用这个DLL ...任何人都可以告诉我如何在C#中声明受尊重的方法并且可以调用这些方法....提前感谢...
答案 0 :(得分:0)
[DllImport("external.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern MbStatus queue_accept(
int reader,
[MarshalAs(UnmanagedType.LPStr)] string status);
查找DllImport属性的参数。根据您的DLL,可能需要调整它们!
旁注:我通常将外部dll包装在一个接口和一个代码层中,以便将其解耦以进行测试,并使用依赖注入加载它。我也不改变命名约定。
public interface IExternalDllInterop
{
MB_STATUS queue_accept(int reader, string status);
}
public class AmbInterop : IAmbInterop
{
public MbStatus queue_accept(int reader, string status)
{
return StaticAmbInterop.mb_queue_accept(reader, message, status);
}
}
答案 1 :(得分:0)
是。您可以。实际上,不是std::string
,std::wstring
,任何标准C ++类或您自己的类都可以被编组或实例化并从C#/ .NET调用。您需要为每个C ++类编写一个包装类,然后才能在.NET中编组它们。
从.NET世界实例化C ++对象的基本思想是从.NET分配C ++对象的确切大小,然后调用从C ++ DLL导出的构造函数来初始化对象,然后您就可以调用任何函数来访问该C ++对象,如果任何方法涉及其他C ++类,您也需要将它们包装在C#类中,对于具有基本类型的方法,您可以简单地P / Invoke它们。如果你只有几种方法可以调用,那很简单,手动编码不会花费很长时间。完成C ++对象后,可以调用C ++对象的析构函数方法,该方法也是导出函数。如果它没有,那么你只需要从.NET中释放你的记忆。
这是一个例子。
public class SampleClass : IDisposable
{
[DllImport("YourDll.dll", EntryPoint="ConstructorOfYourClass", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.ThisCall)]
public extern static void SampleClassConstructor(IntPtr thisObject);
[DllImport("YourDll.dll", EntryPoint="DoSomething", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.ThisCall)]
public extern static void DoSomething(IntPtr thisObject);
[DllImport("YourDll.dll", EntryPoint="DoSomethingElse", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.ThisCall)]
public extern static void DoSomething(IntPtr thisObject, int x);
IntPtr ptr;
public SampleClass(int sizeOfYourCppClass)
{
this.ptr = Marshal.AllocHGlobal(sizeOfYourCppClass);
SampleClassConstructor(this.ptr);
}
public void DoSomething()
{
DoSomething(this.ptr);
}
public void DoSomethingElse(int x)
{
DoSomethingElse(this.ptr, x);
}
public void Dispose()
{
Marshal.FreeHGlobal(this.ptr);
}
}
有关详细信息,请参阅以下链接
(我是SDK工具的作者)
一旦准备好了C ++类的C#包装类,就可以很容易地实现ICustomMarshaler
,这样就可以从.NET编组C ++对象了。
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.icustommarshaler.aspx