简体   繁体   中英

Crash With DllImport C#

Gang,

I'm using a third-party API written in (what looks like) MFC C++. My application is a WinForms app in C#. The API's company has a C# demo application, and I used their code verbatim. The relevant code looks like this...

API's C++ Function:

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
}

The DllImport Statement:

[DllImport("api.dll")]
extern public static int CppFunction(ref byte pbAdapter, ref byte pbTargetID, string pcVendor, string pcProduct, string pcRelease, int iMessageBox);

My C# Logic:

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);
    }
}

This is the code as it exists in their C# sample. When run, it crashes with a "FatalExecutionEngineError" even in a try/catch.

在此处输入图片说明

I don't know PInvoke very well, but don't those variables have to be marshaled as an unmanaged type? Any help would be appreciated.

I am taking a wild guess here, but I am pretty sure it will be the right answer

Lets take a look to the function definition:

int PASCAL CppFunction(
    BYTE *pbAdapterID, 
    BYTE *pbTargetID, 
    char *pcVendor, 
    char *pcProduct, 
    char *pcRelease, 
    int iMessageBox);

And the corresponding DllImport declaration:

[DllImport("api.dll")]
extern public static int CppFunction(
    ref byte pbAdapter, 
    ref byte pbTargetID, 
    string pcVendor, 
    string pcProduct, 
    string pcRelease,
    int iMessageBox);

There are a lot of parameters there, some of them caught my attention:

    char *pcVendor, 
    char *pcProduct, 
    char *pcRelease,

They are not passed by reference, are they being modified by the library?

Note: That why I asked you to give details about the function.

I that's the case, you cannot marshal strings because the datatype string is immutable, you must use the StringBuilder class, just make sure the StringBuilder has enough Capacity .

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM