DllImport C# 崩溃
Crash With DllImport C#
帮派,
我正在使用用(看起来像)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,但这些变量不是必须作为非托管类型进行封送处理吗?任何帮助将不胜感激。
我在这里胡乱猜测,但我很确定这将是正确的答案
让我们看一下函数定义:
int PASCAL CppFunction(
BYTE *pbAdapterID,
BYTE *pbTargetID,
char *pcVendor,
char *pcProduct,
char *pcRelease,
int iMessageBox);
以及对应的DllImport声明:
[DllImport("api.dll")]
extern public static int CppFunction(
ref byte pbAdapter,
ref byte pbTargetID,
string pcVendor,
string pcProduct,
string pcRelease,
int iMessageBox);
那里有很多参数,其中一些引起了我的注意:
char *pcVendor,
char *pcProduct,
char *pcRelease,
它们不是通过引用传递的,它们是否被库修改了?
注意:这就是我要求您提供有关该功能的详细信息的原因。
我就是这样,你不能编组字符串,因为数据类型字符串是不可变的,你必须使用 StringBuilder
class,只要确保 StringBuilder
有足够的 [=16] =].
int result = 0;
StringBuilder strVendorBuffer = new StringBuilder(1024); // up to 1024 chars
StringBuilder strProductBuffer = new StringBuilder(1024); // up to 1024 chars
StringBuilder strReleaseBuffer = new StringBuilder(1024); // up to 1024 chars
StringBuilder strSerial = string.Empty;
byte bAdapt = 0;
byte bTarg = 0;
result = CppFunction(ref bAdapt, ref bTarg, strVendorBuffer, strProductBuffer, strReleaseBuffer, 0);
帮派,
我正在使用用(看起来像)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,但这些变量不是必须作为非托管类型进行封送处理吗?任何帮助将不胜感激。
我在这里胡乱猜测,但我很确定这将是正确的答案
让我们看一下函数定义:
int PASCAL CppFunction(
BYTE *pbAdapterID,
BYTE *pbTargetID,
char *pcVendor,
char *pcProduct,
char *pcRelease,
int iMessageBox);
以及对应的DllImport声明:
[DllImport("api.dll")]
extern public static int CppFunction(
ref byte pbAdapter,
ref byte pbTargetID,
string pcVendor,
string pcProduct,
string pcRelease,
int iMessageBox);
那里有很多参数,其中一些引起了我的注意:
char *pcVendor,
char *pcProduct,
char *pcRelease,
它们不是通过引用传递的,它们是否被库修改了?
注意:这就是我要求您提供有关该功能的详细信息的原因。
我就是这样,你不能编组字符串,因为数据类型字符串是不可变的,你必须使用 StringBuilder
class,只要确保 StringBuilder
有足够的 [=16] =].
int result = 0;
StringBuilder strVendorBuffer = new StringBuilder(1024); // up to 1024 chars
StringBuilder strProductBuffer = new StringBuilder(1024); // up to 1024 chars
StringBuilder strReleaseBuffer = new StringBuilder(1024); // up to 1024 chars
StringBuilder strSerial = string.Empty;
byte bAdapt = 0;
byte bTarg = 0;
result = CppFunction(ref bAdapt, ref bTarg, strVendorBuffer, strProductBuffer, strReleaseBuffer, 0);