0

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?

9
  • You might be missing that char is MBCS, not Unicode. Try to change that to wchar_t. But I think there is more missing. Have you tried doing it the other way around, i.e. creating a C++/CLR wrapper (managed C++) around your C library and use that instead of directly messing with DllImport? Commented Oct 18, 2016 at 9:33
  • You declare your method as CharSet = CharSet.Unicode, but it looks like it's using 8 bit chars to me. Secondly, str[0] = h[0];... Should that not be str[i] = h[i];? Actually, it looks like there may be other bugs in the C function. I would suggest you (unit) test it properly within the C environment, before trying to call it from C#. Commented Oct 18, 2016 at 9:34
  • @KrisVandermotten That's what I get for writing code early in the morning. I also tried CharSet.Ansi but neither seemed to work. Commented Oct 18, 2016 at 9:37
  • @ConorWatson Why would you write Unicode when you know that it is Ansi. Don't attempt to write code by trial and error. Commented Oct 18, 2016 at 9:40
  • @donmartin Would I not still have to use DllImport? Commented Oct 18, 2016 at 9:42

1 Answer 1

3

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.

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

Comments

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.