Conor Watson
Conor Watson

Reputation: 617

Passing String from C function to C#

I have the following test function set up in a C project:

__declspec(dllexport) int test(char *str, int strlen){
    char* h = "Hello";
    int length = 5;
    for(int i = 0; i < length; i++){
        str[0] = h[0];
    }
    return strlen;
}

And in my C# project I declare the method as follows:

 [DllImport("solver.dll", CharSet = CharSet.Unicode ,CallingConvention = CallingConvention.Cdecl)]
 public static extern int test(StringBuilder sol, int len);

And I try to use it in my project like so:

StringBuilder sol = new StringBuilder(15);
int t = test(sol, sol.Capacity);
string str = sol.ToString();

I'd like to pass "Hello" back to the C# code as a test, but when I run the code the StringBuilder stays empty, and even though 15 is passed to the C function as the length, when the C function returns the length it returns a 'random' large number like 125822695. What am I missing?

Upvotes: 0

Views: 474

Answers (1)

David Heffernan
David Heffernan

Reputation: 613013

A number of problems:

  1. You state CharSet.Unicode in the C#, but use ANSI in the unmanaged code.
  2. You only write to the first character.
  3. You ignore the value of strlen passed to the function.
  4. You don't attempt to write a null-terminator.

As for the value returned from the function, that cannot be explained by the code that you present. There is something missing from your question that we need to see in order to explain that.

It is quite common when we see these questions, that the unmanaged code is clearly broken. It's hard enough to write correct p/invokes to correct unmanaged code. Trying to debug the p/invoke and the unmanaged code at the same time is so much harder. Test your unmanaged code in an unmanaged setting first. Only when you are confident it is correct should you move to write your p/invoke.

Upvotes: 3

Related Questions