Ekim,
You have a few problems with this code. First, you are passing a
pointer to a character, this is the same as an array of characters.
However, inside the function, you are reassigning the pointer. Because the
pointer is what was actually passed to the function, the reassignment never
takes place (a copy of the pointer was passed in and the original is not
touched).
Now, you could change the parameter to a double pointer, but that would
be a bad idea. The reason for this is that you are causing a reassignment
to the original pointer, and you are not indicating the memory allocation
scheme (is it through the COM allocator, new, malloc). Because of this, you
might not be able to free the memory correctly.
Because of that, you should pass the pointer in to a pre-allocated
buffer (along with the length) and then copy the contents into the buffer.
Now, here is the problem. You say you can not change the type in C# to
any other data type. You must do this. The reason for this is that
marshaling through the P/Invoke layer does not marshal back arrays. The
reason for this is that the runtime doesn't know upon returning how much of
the array to marshal. Now, you can get around this by using a
StringBuilder, as suggested before, and allocating the buffer to a large
amount (in the case you can't change the C++ code). However, this will most
likely result in a memory leak of some kind, if the contents aren't copied
to the buffer, and you are just trying to reassign).
You could also marshal the contents manually, declaring the type as
IntPtr, and marshaling the array yourself across the boundary, and then
back, but that's not worth it, since you have the functionality using the
StringBuilder already. If anything, you can make the API call private, and
create a wrapper which performs the appropriate conversions.
Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)
Ekim said:
hy to all,
I'm accessing a function from a managed-c++-dll within my c#-application.
Therefore I encountered following troubles:
In my c#-app I have got a byte[]-array, which should somehow be mapped to
a
char* in my managed-c++-function.
Here is the prototype:
---------------------- managed c++ class library
project -------------------------------
void MyFunction(char* buffer)
{
buffer = "Hello from managed c++!";
}
----------------------------------------------------------------------------
------------
in c# I'm using this function like this:
-----------------------
c#-application -------------------------------------------------
[DllImport("c++ClassLib.dll")] // import the c++
dll
private extern static void MyFunction(ref byte[] byteStream);
within any function, for example button1-Click()
{
byte[] byteStream = new byte[4000]; // create new byte stream
MyFunction(ref byteStream); // call c++ function
MessageBox.Show(byteStream.toString()); // test-output the data
}
----------------------------------------------------------------------------
------------
The above code works (means throws no exception or something like this),
but
has not the desired effect (that is, a displayed messagebox that says
"Hello
from managed c++!"). So what I want to do in the c++-dll is to write
something into the byteStream that is provided by the c#-application).
Under no circumstances I can change the byte-stream to any other datatype
(because it is provided to me by another function), nor can I change the
char*-buffer in my c++-dll, because it is used by another external
function,
too.
On the other hand, I could use some "intermediate" data types like an
Array
if this would make things work (that is first converting the byteStream to
the Array, call the function, and within MyFunction convert the Array back
to char*).
I appreciate your help sincerely,
ekim!