Sending a buffer to C++ DLL

D

dollardan

Hi,

I've read through the forum and I couldn't get my code to run with any
of the solution I found there.

My project has 3 main components:
Legacy.dll - unmanaged C++
DotNet.dll - C# Class Library. Interop for the Legacy DLL
TestApp.exe

My Problem:
I'm trying to send a buffer to the DotNet.dll from the TestApp for it
to forward to the Legacy.dll. I an having trouble writing the DLL and
calling its methods.
The buffer only contains data that I want the Legacy DLL to read.
That's it. It seems simple enough to do, but I keep tripping the
AccessViolationException:
Attempted to read or write protected memory. This is often an
indication that other memory is corrupt.

Legacy DLL:
bool SetData( UCHAR *buffer, int size);

DotNet DLL:
public static class DotNet
{
[DllImport("Legacy.dll")]
public static extern bool SetData(String buffer, int size);
}

TestApp:
static private char[] charArray = new char[50000];
// charArray is filled with data

/*** Attempt 1 ***/
static private byte[] myBuffer = new byte[50000];

/*** Attempt 2 ***/
static private String myBuffer = new String(charArray);

/*** Attempt 3 ***/
static private StringBuilder myBuffer = new StringBuilder(new
string(charArray));

/*** Attempt 4 ***/
static private IntPtr myBuffer =
Marshal.StringToHGlobalAnsi(charArray);

DotNet.SetData(myBuffer, 1000)

I've Tried:
unsafe tags
[MarshalAs()] Attribute (in the Interop)
declaring the buffer as byte[], String, string, IntPtr, and
StringBuilder (in the TestApp and the DotNet DLL)
Marshal.StringToHGlobalAuto( myString ) when using IntPtr

The Exception is as far as I can get, and I don't know why it just
won't work. Please help.

Thanks,

Daniel.
 
J

Jeroen Mostert

I've read through the forum and I couldn't get my code to run with any
of the solution I found there.

My project has 3 main components:
Legacy.dll - unmanaged C++
DotNet.dll - C# Class Library. Interop for the Legacy DLL
TestApp.exe

My Problem:
I'm trying to send a buffer to the DotNet.dll from the TestApp for it
to forward to the Legacy.dll. I an having trouble writing the DLL and
calling its methods.
The buffer only contains data that I want the Legacy DLL to read.
That's it. It seems simple enough to do, but I keep tripping the
AccessViolationException:
Attempted to read or write protected memory. This is often an
indication that other memory is corrupt.

Legacy DLL:
bool SetData( UCHAR *buffer, int size);

DotNet DLL:
public static class DotNet
{
[DllImport("Legacy.dll")]
public static extern bool SetData(String buffer, int size);
}
Two important things missing here: you must inform the marshaler that the
string is not Unicode (as I presume it's not), and that the bool you're
returning is a C++ bool rather than a Win32 BOOL.

[DllImport("Legacy.dll", CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.U1)]
public static extern bool SetData(string buffer, int size);

With these changes, it should just work:

string input = "Hello there!";
SetData(input, input.Length);

Note that it's vitally important that the string you pass to SetData is not
modified. Otherwise, you need to use StringBuilder to marshal the data
across instead.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top