473,503 Members | 1,831 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

conversion c#-bytearray to c++-char*

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!
Nov 16 '05 #1
13 12663
Hi,

Quick tip:

replace "ref byte[]" with "StringBuilder" (System.Text)
e.g.:
private extern static void MyFunction(StringBuilder byteStream);

HTH

Marcin
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!

Nov 16 '05 #2
"Marcin Grzębski" <mg*******@taxussi.no.com.spam.pl> wrote in message
news:ch**********@nemesis.news.tpi.pl...
Hi,

Quick tip:

replace "ref byte[]" with "StringBuilder" (System.Text)
e.g.:
private extern static void MyFunction(StringBuilder byteStream);

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
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.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

as I said before, I MUST use a byte-array. I thought it shouldn't be that
difficult, because as far as I know is a byte-array in C# (one byte per
element) the same as a char-array in C++ (one byte per element, too) -
nothingtheless, it doesn't work right now.

by ekim
Nov 16 '05 #3
Hmmm...
It works with APIs functions, but i may be wrong.

first of all... are you sure that this code do
what you want to do?

buffer = "Hello from managed c++!";

I worked with "string.h" (strcpy) to do any
string copies in past.
This function doesn't change your input "buffer"!
It change the reference only int function body.

Try using the "strcpy" and then check my code.

Regards

Marcin
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

as I said before, I MUST use a byte-array. I thought it shouldn't be that
difficult, because as far as I know is a byte-array in C# (one byte per
element) the same as a char-array in C++ (one byte per element, too) -
nothingtheless, it doesn't work right now.

by ekim

Nov 16 '05 #4
"Marcin Grzębski" <mg*******@taxussi.no.com.spam.pl> wrote in message
news:ch**********@nemesis.news.tpi.pl...
Hmmm...
It works with APIs functions, but i may be wrong.

first of all... are you sure that this code do
what you want to do?

buffer = "Hello from managed c++!";

I worked with "string.h" (strcpy) to do any
string copies in past.
This function doesn't change your input "buffer"!
It change the reference only int function body.

Try using the "strcpy" and then check my code.

Regards

Marcin
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

as I said before, I MUST use a byte-array. I thought it shouldn't be that difficult, because as far as I know is a byte-array in C# (one byte per
element) the same as a char-array in C++ (one byte per element, too) -
nothingtheless, it doesn't work right now.

by ekim


yeah, I admit you may be right - but within managed c++, you cannot use
strcpy (unresolved external symbol)
do you know how to do that in managed c++?

thx
Nov 16 '05 #5
"Ekim" <th************@gmx.net> wrote in message
news:2q************@uni-berlin.de...
"Marcin Grzębski" <mg*******@taxussi.no.com.spam.pl> wrote in message
news:ch**********@nemesis.news.tpi.pl...
Hmmm...
It works with APIs functions, but i may be wrong.

first of all... are you sure that this code do
what you want to do?

buffer = "Hello from managed c++!";

I worked with "string.h" (strcpy) to do any
string copies in past.
This function doesn't change your input "buffer"!
It change the reference only int function body.

Try using the "strcpy" and then check my code.

Regards

Marcin
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

as I said before, I MUST use a byte-array. I thought it shouldn't be that difficult, because as far as I know is a byte-array in C# (one byte per element) the same as a char-array in C++ (one byte per element, too) -
nothingtheless, it doesn't work right now.

by ekim


yeah, I admit you may be right - but within managed c++, you cannot use
strcpy (unresolved external symbol)
do you know how to do that in managed c++?

thx


okay, let me correct something - I've already tried to convert a string to
char*, and this works fine. it is done in this way:
---------------------- managed c++ class library
project -------------------------------
void MyFunction(char** buffer) // pointer to pointer!
{
*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 int ConvertPDF(ref string stringBuffer);

within any function, for example button1-Click()
{
string buffer = @"text before function"; // create new string
MyFunction(ref stringBuffer); // call c++ function
MessageBox.Show(stringBuffer); // test-output the data
}
----------------------------------------------------------------------------
------------

this code really works fine, means that it displays "Hello from managed C++"
in the messagebox. As far as I use a pointer to pointer (see code above), I
can make a statement like *buffer = "Hello from managed c++!";
and it works.

Anyways, once again I don't need a string but would need a byte-Array on the
Csharp-side instead.
Nov 16 '05 #6
> yeah, I admit you may be right - but within managed c++, you cannot use
strcpy (unresolved external symbol)
do you know how to do that in managed c++?


if simple '#include <string.h>' doesn't work then
i have no idea.

I didn't work in managed C++.

Marcin
Nov 16 '05 #7
> if simple '#include <string.h>' doesn't work then
i have no idea.

I didn't work in managed C++.

Marcin


no, it doesn't work
Nov 16 '05 #8
It's easy to convert a byte array to a string

byte[] byteStream = new byte[4000]; // create new byte stream
string buffer =
System.Text.Encoding.Unicode.GetString(byteStream, 0,byteStream.Length);
MyFunction(ref buffer); // call c++ function
MessageBox.Show(buffer); // test-output the data

The System.Text.Encoding class also supports other encoding types in
addition to Unicode, check to see what suits you best.

Regards,
John Wadie

Nov 16 '05 #9
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]
- mv*@spam.guard.caspershouse.com

"Ekim" <th************@gmx.net> wrote in message
news:2q************@uni-berlin.de...
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!

Nov 16 '05 #10
"John Wadie" <jo********@hotmail.com> wrote in message
news:DW**************@cpmsftngxa10.phx.gbl...
It's easy to convert a byte array to a string

byte[] byteStream = new byte[4000]; // create new byte stream
string buffer =
System.Text.Encoding.Unicode.GetString(byteStream, 0,byteStream.Length);
MyFunction(ref buffer); // call c++ function
MessageBox.Show(buffer); // test-output the data

The System.Text.Encoding class also supports other encoding types in
addition to Unicode, check to see what suits you best.

Regards,
John Wadie


hy john,
thx for your suggestion. Although I don't quite like the idea of converting
the byteStream first to a string, call the function and afterwards convert
it back into a byteStream, I guess that's a way it could serve me. (I don't
like it because it is a quite time-critical application that converts a lot
of files and is called thousand of times within a short period - therefore I
would have preferred a direct way, that is directly from byteArray to char*)
Besides the byteArray, before I call the function, is allocated, but has no
reasonable content, and therefore it's nonsense to convert it to a
Unicode-string.

So, my real question is now, how can I back-transform the string into a
byte-array?

by ekim
Nov 16 '05 #11
Well, I haven't tried this method on such a huge amount of data before,
give it a try and let us know the results.

To convert the string back to a byte array:

byteStream = System.Text.Encoding.Unicode.GetBytes(buffer);

Regards,
John Wadie

Nov 16 '05 #12
Hi,

<snip>
void MyFunction(char** buffer) // pointer to pointer!
{
*buffer = "Hello from managed c++!";
}
From my PoV this code will not work as you want it.
There is not much sense to return const string.

And any memory allocations (e.g. *buffer=new char[32])
will execute on "imported dll's" side.

But, if you want to fill the buffer (passed by reference)
then definition:
void MyFunction(char* buffer) // pointer to pointer!
{
FillTheBuffer(buffer);
}
will be more suitable here.

If you can not use functions of <string.h> then you can
define function:

void MyFunction(char* buffer, int bufferLength)
{
// e.g.
for(int i=0; i<(bufferLength-1); i++) {
buffer[i]='a' + (i%('z'-'a'));
}
buffer[i]='\0';
}
----------------------------------------------------------------------------

in c# I'm using this function like this:
-----------------------
c#-application -------------------------------------------------
[DllImport("c++ClassLib.dll")] // import the c++ dll
private extern static int ConvertPDF(ref string stringBuffer);


Maybe this link could help you:

http://groups.google.com/groups?hl=p...09%26rnum%3D18

Marcin
Nov 16 '05 #13
"Ekim" <th************@gmx.net> wrote in message
news:2q************@uni-berlin.de...
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!


after all, I figured out that there may be another good way in doing this:
I mean, I will give in the pre-allocated byteArray from C# to my
c++-function, and now as parameter of the c++-function it could be something
like byte __gc[] (instead of using char** buffer before).
I read something about this type, and that it belongs to something like the
so called managed c++ extensions - unfortunately, I didn't manage to make it
work yet.
But passing a byteArray from c# to c++ with this type could work I guess -
subsequently, I only have to find a method to fill the byte __gc[]-array
within my c++-function with the content of my char*-buffer.

Has anybody an idea if my described method could work (and how I have to
specify the parameters exactly) and how I could copy the char*-buffer into
the __gc[]-byteArray in managed c++?

thx again,
ekim

Nov 16 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
5637
by: Stub | last post by:
Docs says that "The compiler does not use an explicit constructor to implement an implied conversion of types. It's purpose is reserved explicitly for construction." I put up code of three cases...
7
3247
by: Michael Lehn | last post by:
Hi, I have a question regarding the conversion of objects. When is the conversion done by the constructor and when by the operator. My feeling tells me that the constructor is preferred. But...
11
7590
by: Steve Gough | last post by:
Could anyone please help me to understand what is happening here? The commented line produces an error, which is what I expected given that there is no conversion defined from type double to type...
2
6859
by: Alex Sedow | last post by:
Why explicit conversion from SomeType* to IntPtr is not ambiguous (according to standart)? Example: // System.IntPtr class IntPtr { public static explicit System.IntPtr (int); public...
3
4434
by: Steve Richter | last post by:
here is a warning I am getting in a C++ .NET compile: c:\SrNet\jury\JuryTest.cpp(55) : warning C4927: illegal conversion; more than one user-defined conversion has been implicitly applied while...
4
6690
by: I.Charitopoulos | last post by:
The reason I want to do so, is that I am sending to DOS and I am pretty certain that it will not work. Everything I've tried so far hasnt. In my test environment (Windows to Windows) this works...
5
5748
by: Ian Rutherford | last post by:
Heya guys, It seems VB .net no longer supports the awesome ability of VB 6 to declare something as a string and specify how long the string would be all in one line: Public myString as String *...
0
2269
by: Lou Evart | last post by:
DOCUMENT CONVERSION SERVICES Softline International (SII) operates one of the industry's largest document and data conversion service bureaus. In the past year, SII converted over a million...
2
3111
bajajv
by: bajajv | last post by:
Hi, I have to replace a CByteArray object by pure C++ function. I am trying with this - vector<vector<char>> charVec; Thanks for your help.
0
7274
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7323
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
5005
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4670
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3162
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3151
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1507
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
732
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
377
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.