orwe
orwe

Reputation: 233

Returning char* from dllexported function

I'm creating a DLL which will be used by some external exe file. One of the exposed function is

...
char *current_version = "1.1";
...

extern "C" _declspec(dllexport) char* version(){ 
  return current_version;
}

Because the current version is used in multiple places I created the current_version variable. Will caller of the version function be able to change the content of current_version variable ? (I expect he'll).

If I'll change the code to:

...
const char *current_version = "1.1"; //this is preferable 
...

extern "C" _declspec(dllexport) char* version(){ 
  char local_copy[100] = make_local_copy(current_version);
  return *local_copy;
}

will the local_copy variable be disposed after execution of the version function finishes (and in this case returned pointer will point at some random data) ? If so, what is the best way to return a pointer to const char* ?

Upvotes: 0

Views: 2617

Answers (3)

Agent_L
Agent_L

Reputation: 5411

Will caller of the version function be able to change the content of current_version variable ?

This is UB, so the actual behavior depends on implementation. There is a good chance that caller indeed could change this constant. In some implementations, string literals are stored in read-only memory, so attempting to write to it through a non-const pointer will throw a runtime error instead.

will the local_copy variable be disposed after execution of the version function finishes

Yes.

(and in this case returned pointer will point at some random data) ?

It will, in most implementations, point to an area of stack. Writing to it would corrupt program execution flow.

If so, what is the best way to return a pointer to const char* ?

There is no good way to do that in C++.

Upvotes: 2

momo9
momo9

Reputation: 26

  1. About the questions, I agree with @Agent_L.

  2. About the solution, I think you can use a static char array as a buffer. Just as follows:

static char local_copy[64];
static char current_version[] = "1.1";

char *version() {
  strcpy(local_copy, current_version);
  return local_copy;
}

Then you don't need to worry about disposing of local_copy.

Upvotes: 0

Aditya Patil
Aditya Patil

Reputation: 558

extern "C" _declspec(dllexport) void version(char* buffer, int* len)
    {
     if (buffer == NULL || *len <= 0)
         {
          char local_copy[100] = make_local_copy(current_version);
          *len = strlen (local_copy);
          return;
         }

     char local_copy[100] = make_local_copy(current_version);
     *len = strlen (local_copy);
     strcpy_s(buffer, *len, local_copy);
     return;
    }

This should be a good starting point. There may be bugs and also I recommend you use wchar instead of char. This is my best guess at a safe function with memory issues. User makes the first call to determine length required. dynamically allocate buffer in calling function and then call this method again. Or allocate memory and assign length if you already know the size of the buffer and the length, you will need to call this function just once.

Upvotes: 0

Related Questions