I have a C++ dll which has a function within it I am trying to call from a C# application.
Here's the code in the C++ header file
extern "C" _declspec(dllexport) int LabelStoringSSDsim(int devNum, UCHAR serial[40], UCHAR wwn[40],
UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode);
Here's the code in the C++ source file
int LabelStoringSSDsim(int devNum, UCHAR serialLbl[40], UCHAR wwnLbl[40],
UCHAR ConfigID[5], UCHAR FrmRev[8], UCHAR DevName[40], int eCode)
{
string strConfigID="12111"; //5 bytes
string strFrmRev="1.25...."; //8 bytes
string strDevName="ABC-123................................."; //40 bytes
for (int i=0;i<5;i++)
ConfigID[i] = strConfigID[i];
for (int i=0;i<8;i++)
FrmRev[i] = strFrmRev[i];
for (int i=0;i<40;i++)
DevName[i] = strDevName[i];
return eCode;
}
Here's the C# relevant code
[DllImport("LabelStoring.dll")]
static extern int LabelStoringSSDsim(
int devNum,
byte[] strserial,
byte[] strwwn,
[In] ref byte[] ConfigID,
[In] ref byte[] FrmRev,
[In] ref byte[] DevName,
int eCode
);
int errNum = LabelStoringSSDsim(devNum, bserial, bwwn, ref ConfigID, ref FrmRev, ref DevName, 123123);
So when I get to the last bit of code there I get the "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." error.
I have no prior experience in importing DLL's like this and I've done a lot of searching but cannot seem to find a solution to the problem.
I tried starting over from scratch with a simple function returning an integer, and that worked. Then I added an int for me to pass to the function and it still worked. Then I added a byte array for me to pass, which worked. Then I attempted to turn that byte array into a reference and it failed. So my guess is I'm getting the data back incorrectly.
Any help is greatly appreciated.
Try changing [In]
to [In, Out]
. I'm also not sure about using both the ref
and [In, Out]
keywords together on a single argument. (Edit: Hans Passant has a good explanation of the differences between the two in his comment below.)
See this MSDN article for more information, especially the passage, "By default, reference types (classes, arrays, strings, and interfaces) passed by value are marshaled as In parameters for performance reasons. You do not see changes to these types unless you apply InAttribute and OutAttribute (or just OutAttribute) to the method parameter."
I started getting this exception durring native interop periodically after upgrading to Windows 7. The code had always worked on XP and has fewer issues on Win 7 if I ran my app in XP compatibility mode.
After some research and experimentation I discovered that the reason I was getting this exception had to do with calling a native function that returned a string (WCHAR*).
I don’t believe there is currently a fix for this as even updating to .Net 3.5 didn’t fix the issue… However I did find the following work around.
Example of what works on XP but doesn’t work on Win 7:
[DllImport("NativeBin.dll")]
public static extern String GetWCharStr();
Example of what works for me on Win 7 and XP:
[DllImport("NativeBin.dll")]
private static extern IntPtr GetWCharStr();
public static String GetString()
{
return Marshal.PtrToStringUni(GetWCharStr());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With