【发布时间】:2016-10-13 15:56:29
【问题描述】:
帮派,
我正在使用用(看起来像)MFC C++ 编写的第三方 API。我的应用程序是 C# 中的 WinForms 应用程序。 API 的公司有一个 C# 演示应用程序,我一字不差地使用了他们的代码。相关代码长这样……
API 的 C++ 函数:
int PASCAL CppFunction(BYTE *pbAdapterID, BYTE *pbTargetID, char *pcVendor, char *pcProduct, char *pcRelease, int iMessageBox)
{
// The function definition is all I can see in the API's documentation
}
DllImport 声明:
[DllImport("api.dll")]
extern public static int CppFunction(ref byte pbAdapter, ref byte pbTargetID, string pcVendor, string pcProduct, string pcRelease, int iMessageBox);
我的 C# 逻辑:
public void CallCppFunction()
{
try
{
int result = 0;
string strVendorBuffer = string.Empty;
string strProductBuffer = string.Empty;
string strReleaseBuffer = string.Empty;
string strSerial = string.Empty;
byte bAdapt = 0;
byte bTarg = 0;
result = CppFunction(ref bAdapt, ref bTarg, strVendorBuffer, strProductBuffer, strReleaseBuffer, 0);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
这是存在于他们的 C# 示例中的代码。运行时,即使在 try/catch 中,它也会因“FatalExecutionEngineError”而崩溃。
我不太了解 PInvoke,但是这些变量不是必须作为非托管类型编组吗?任何帮助将不胜感激。
【问题讨论】:
-
我很确定我知道答案,但你需要告诉我
CppFunction应该首先做什么。 -
这是一个猜测。这可能是由于您的字符串处理(您没有指定如何编组它们,使用
[MarshalAs])。如果输出的是字符串参数,应该使用StringBuilder而不是string(带有一些预分配的存储空间) -
如果不知道界面是什么,没有人可以说。 C++ 函数原型没有定义接口。
ref byte几乎可以肯定是错误的。但它应该是什么?我们怎么可能知道所提供的信息?我们可以猜测,但你真的会通过猜测来写代码吗? -
您可能不需要使用 dllImport。您可能只需要添加 dll 作为参考,并在模块顶部添加适当的“使用”语句。
-
@jdweng 真的。你认为这是一个托管 DLL?
标签: c# c++ pinvoke marshalling dllimport