Vikneshwar
Vikneshwar

Reputation: 1033

Calling C++ code from C# error using references in c++

In my C++ dll named "scandll.dll" I have the following function

extern "C" __declspec(dllexport) void scanfile(char * returnstring)
{
    strcpy(returnstring, "return string");
}

in my C# code I'm doing this

[DllImport("scandll.dll", CharSet = CharSet.Ansi, SetLastError = true )]
public static extern int scanfile(ref IntPtr strReturn);

and this is the method that I'm using to get the value from the dll

public void Scan()
{
     string filename = "";
     IntPtr ptr = new IntPtr();
     scanfile(ref ptr);//Here i get the error
     filename = Marshal.PtrToStringAnsi(ptr);
}

I get an exception thrown as "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

I'm following this link

Calling C++ code from C# error using references in c++ ref in c#

Any help would be appreciated.

Thanks

Upvotes: 0

Views: 107

Answers (2)

Will Dean
Will Dean

Reputation: 39500

Your C++ code is wrong - all it's doing is changing the value of the pointer which has been passed to it to point to a constant string. The caller knows nothing about that change.

It's the same as if you'd done this:

void MyCfunction(int number)
{
   number = 3;
}

and then hoped that a caller of that function would somehow see the number '3' anywhere.

You could do something like this in C++:

void MyCFunction(char* pReturnString)
{
 strcpy(pReturnString, "Hello, world");
}

but you also need to make sure on the C# side that you had provided a buffer with pReturnString pointing to it. One way to do this by using a StringBuilder, and then having your C# declaration of the C function take a parameter like this:

[MarshalAs(UnmanagedType.LPStr)] StringBuilder returnString

You need to reserve space in the StringBuilder before calling into the C++ function.

In real life, C/C++ functions like this pretty much always take an additional length parameter, which allows the caller to tell the callee the maximum length of string it's allowed to copy into the buffer. There is no consistency of convention about whether the length includes the terminating \0 or not, so people are often careful about running right up to the end of the buffer.

Upvotes: 4

Vinay Shukla
Vinay Shukla

Reputation: 1844

  memcpy (  destination,  * source, size_t num );

Try this to assign the value to returnstring = "rturn name";

Upvotes: 0

Related Questions