1

I have the following function, written as part of another class in C:

int example(char *remoteServerName)
{
    if (doSomething(job))
        return getError(job);
    if (job->server != NULL) {
        int length = strlen(jobPtr->server->name); // name is a char * of length 1025
        remoteServerName = malloc (length * sizeof(char));
        strncpy(remoteServerName, jobPtr->server->name, length);
    }
    return 0;
}

How can I get the remoteServerName back from it? I have tried the following:

[DllImport("example.dll")]
public static extern int example(StringBuilder remoteServerName);

var x = new StringBuilder();
example(x);
Console.WriteLine(x.ToString());

But the string is always empty.

1
  • C does not support classes. Commented Mar 21, 2017 at 14:33

1 Answer 1

4

You need to allocate some space for the string to be returned in. Instead of:

var x = new StringBuilder();

provide a capacity value:

var x = new StringBuilder(1024);

You should also remove your call to malloc. The caller allocates the memory. That is the purpose of marshalling with StringBuilder.

You are not using strncpy correctly, and so fail to write a null terminator. You could pass the buffer length like this:

int example(char *remoteServerName)
{
    if (doSomething(job))
        return getError(job);
    if (job->server != NULL) {
        // note that new StringBuilder(N) means a buffer of length N+1 is marshaled
        strncpy(remoteServerName, jobPtr->server->name, 1025);
    }
    return 0;
}

But that would be a bit wasteful, with all the zero padding that is implied. Really, strncpy is next to useless and you should use a different function to copy, as has been discussed many times before here. I don't really want to get drawn into that because it's a little off to the side of the question.

It would be prudent to design your API to allow the caller to also pass the length of the character array so that the callee can make sure not to overrun the buffer, and so that you don't need to use magic constants as the code here does.

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

10 Comments

I am trying this but there is something else not working here, because its still empty. I can verify that the int length variable has a value of 9.
Yes, there were other mistakes in your code that I did not see originally. Sorry. Now fixed, I hope.
@Alexandru For an example of how the Windows API manages buffer size reporting, see GetWindowText() and GetWindowTextLength()
David, I hate bringing this up but this code you posted has a bit of a small problem, but the solution to it is in the following link. Perhaps you could update your answer in order to take this into account? stackoverflow.com/questions/45103396/…
@Alexandru Can you explain what is wrong with this answer to this question?
|

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.