0

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

4
  • 1
    Your C function is already wrong. Why do you need to have a C function when you have problems writing one? Can't you use a managed function? Commented Nov 22, 2013 at 12:56
  • Setting CharSet.Ansi does nothing when you're manually marshaling strings. In fact in this particular case it might slow down the call because the runtime would look for scanfileA before looking for scanfile Commented Nov 22, 2013 at 12:58
  • @nvoigt that dll is further linked with other c++ dll's. I found it the better way to go with this method. Commented Nov 22, 2013 at 13:18
  • @Vikneshwar if you are really using that link as a guide, you are missing the & that makes it a reference in C++. Look at / re-read the accepted answer. Commented Nov 22, 2013 at 13:22

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

Comments

0
  memcpy (  destination,  * source, size_t num );

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

1 Comment

I forgot to add strcpy. But still im stuck on with the same issue. Im getting the same error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.