简体   繁体   中英

How to handle IntPtr returned from a C++ DLL in C#?

I am quite new to C# and I have build a class ProcessData that wraps a C++ DLL from manufacturer (I can't access to the code in this DLL). One of the method of the C++ DLL return a pointer (void far*) to a HandleFile.xyz that is on my hard drive but the content of this file is unknown to me. Another method re-use this pointer do process my data, as you can see in the code below.

    public class ProcessData
{

    [DllImport("myfile.dll", EntryPoint = "LoadFile", SetLastError = true, CharSet = CharSet.None)]
    public static extern IntPtr dLoadFile(string filePath);

    [DllImport("myfile.dll", EntryPoint = "WorkWithFile", SetLastError = true, CharSet = CharSet.None)]
    public static extern uint dWorkWithFile(IntPtr fileHandle, int mydata);

    public IntPtr currentFileHandle; 

    public void LoadFile(string filePath)
    {
    currentFileHandle = dLoadFile(filePath);
    }

    public uint WorkWithFile(int mydata)
    {
    uint x = dWorkWithFile(currentFileHandle, mydata);
    return x;
    }
}

If I try this when loading a single HandleFile.xyz, everything works well and the value returned by WorkWithFile makes sense.

The problem comes when I try to use ProcessData in another class as a List, because at the end, I need to process my data using multiple different HandleFile1.xyz, HandleFile2.xyz, HandleFile3.xyz that are loaded successively using different ProcessData object in a foreach loop. Each ProcessData object contains only the pointer to the corresponding HandleFileX.xyz.

The first iteration of the loop goes well, but the second iteration crashes on dWorkWithFile(currentFile, mydata) returning the following error:

Exception thrown at 0x07DE4C2A (myfile.dll) in MyProgram.exe: 0xC0000005: Access violation reading location 0x00000000.

I am suspecting that this might have to do with the way I initialize my pointer when creating the ProcessData objects as this post might suggest: https://stackoverflow.com/a/10479020/8298327

Is currentFileHandle = dLoadFile(filePath); the proper way to initialize my pointer or should I use some Marshalling, and if yes, how ? Could you provide an example?

Any other idea what could cause this issue?

Ok, if anyone runs into this issue, you need to Unload the .xyz file after each iteration in the foreach loop using the UnFileLoad method.

public void UnLoadFile(IntPtr currentFileHandle)
{
uint = dUnLoadFile(currentFileHandle);
}

And that's what I was doing when processing the ProcessData objects. However I had also a method to Initialize the ProcessData objects and there I was not UnLoading the files. I could Initialize all my objects without problem (which is strange) but the program crashed when starting the processing.

Thanks to jdweng for the advices!

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