eVC++ DLL help

B

Brian

Hi all,

I'm collaborating on a project with another developer, he's the C++ guy, I'm
the .NET guy, and getting my code to talk to his code is causing some
headaches. I'm hoping some of this is simple.

In the C++ dll, there's a function defined like (chopping off the extern
"c", et. al.):
.... int WINAPI Play(char * Filename,int Loop, int Sync)

What is the proper way (VB.NET or C#) to pass in the filename in my
P/Invoke? Right now I've got (realizing the string likely won't cut it):

<DllImport("mydll.dll")> Public Shared Function Play(ByVal Filename As
String, ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

Similarly there are functions that return char*, such as (chopping off the
extern "c", et. al.):
.... char* WINAPI Test();

I've seen a few posts around the net on similar issues using a byte array or
stringbuilder, but am feeling a tad lost right now...

Thanks for the help!

Brian
 
A

Alex Feinman [MVP]

String would cut it just fine as long as the parameter is LPCWSTR. If you
need to pass char string (ANSI), declare the parameter as byte array on the
CF side. If you need to pass a buffer that is to be filled on the unmanaged
side, use StringBuilder type preallocated to the required size

Returning char* (or wchar*) is subject to the same considerations plus one
more thing. Do not return dynamic buffers (allocated with new[]). You can
return pointers allocated using CoTaskMemAlloc or LocalAlloc and use
P/Invoke to free this memory, or if you want to use new, provide a function
that would free memory for you on the unmanaged side
 
B

Brian

Thanks Alex--

In the first case, I've tried passing the byte array (and many other
variants) but no luck yet. I tested the function by hard coding the
filename (the parameter getting passed) in the eVC++ method, and it works.
Without it, the method is returning a file not found error, which seems to
indicate that it's getting passed incorrectly, since hard coding it within
the DLL works.

In using the byte array, I've tried the following:
<DllImport("myDLL.dll")> Public Shared Function FmodPlay(ByVal filename
As byte(), ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

And in my code, I tried the following;

Dim strFilename As String = "test.mp3"
Dim myByteArray As Byte()
Dim a As New System.Text.UTF8Encoding
myByteArray = a.GetBytes(strFilename)

Tried a few variations off this as well, still getting a file not found. Do
you see anything obvious that's wrong?

Brian



Alex Feinman said:
String would cut it just fine as long as the parameter is LPCWSTR. If you
need to pass char string (ANSI), declare the parameter as byte array on the
CF side. If you need to pass a buffer that is to be filled on the unmanaged
side, use StringBuilder type preallocated to the required size

Returning char* (or wchar*) is subject to the same considerations plus one
more thing. Do not return dynamic buffers (allocated with new[]). You can
return pointers allocated using CoTaskMemAlloc or LocalAlloc and use
P/Invoke to free this memory, or if you want to use new, provide a function
that would free memory for you on the unmanaged side

Brian said:
Hi all,

I'm collaborating on a project with another developer, he's the C++ guy, I'm
the .NET guy, and getting my code to talk to his code is causing some
headaches. I'm hoping some of this is simple.

In the C++ dll, there's a function defined like (chopping off the extern
"c", et. al.):
... int WINAPI Play(char * Filename,int Loop, int Sync)

What is the proper way (VB.NET or C#) to pass in the filename in my
P/Invoke? Right now I've got (realizing the string likely won't cut it):

<DllImport("mydll.dll")> Public Shared Function Play(ByVal Filename As
String, ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

Similarly there are functions that return char*, such as (chopping off the
extern "c", et. al.):
... char* WINAPI Test();

I've seen a few posts around the net on similar issues using a byte
array
or
stringbuilder, but am feeling a tad lost right now...

Thanks for the help!

Brian
 
A

Alex Feinman [MVP]

Please try changing the function definition in C++ to accept LPCTSTR and the
P/Invoke definition to use string type for the corresponding parameter

Brian said:
Thanks Alex--

In the first case, I've tried passing the byte array (and many other
variants) but no luck yet. I tested the function by hard coding the
filename (the parameter getting passed) in the eVC++ method, and it works.
Without it, the method is returning a file not found error, which seems to
indicate that it's getting passed incorrectly, since hard coding it within
the DLL works.

In using the byte array, I've tried the following:
<DllImport("myDLL.dll")> Public Shared Function FmodPlay(ByVal filename
As byte(), ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

And in my code, I tried the following;

Dim strFilename As String = "test.mp3"
Dim myByteArray As Byte()
Dim a As New System.Text.UTF8Encoding
myByteArray = a.GetBytes(strFilename)

Tried a few variations off this as well, still getting a file not found. Do
you see anything obvious that's wrong?

Brian



Alex Feinman said:
String would cut it just fine as long as the parameter is LPCWSTR. If you
need to pass char string (ANSI), declare the parameter as byte array on the
CF side. If you need to pass a buffer that is to be filled on the unmanaged
side, use StringBuilder type preallocated to the required size

Returning char* (or wchar*) is subject to the same considerations plus one
more thing. Do not return dynamic buffers (allocated with new[]). You can
return pointers allocated using CoTaskMemAlloc or LocalAlloc and use
P/Invoke to free this memory, or if you want to use new, provide a function
that would free memory for you on the unmanaged side

Brian said:
Hi all,

I'm collaborating on a project with another developer, he's the C++
guy,
I'm
the .NET guy, and getting my code to talk to his code is causing some
headaches. I'm hoping some of this is simple.

In the C++ dll, there's a function defined like (chopping off the extern
"c", et. al.):
... int WINAPI Play(char * Filename,int Loop, int Sync)

What is the proper way (VB.NET or C#) to pass in the filename in my
P/Invoke? Right now I've got (realizing the string likely won't cut it):

<DllImport("mydll.dll")> Public Shared Function Play(ByVal Filename As
String, ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

Similarly there are functions that return char*, such as (chopping off the
extern "c", et. al.):
... char* WINAPI Test();

I've seen a few posts around the net on similar issues using a byte
array
or
stringbuilder, but am feeling a tad lost right now...

Thanks for the help!

Brian
 
B

Brian

Will do... in the meantime: the dll that this is wrapping needs a char * as
a parameter: how can I convert the LPCTSTR to a char*?

-Brian

Alex Feinman said:
Please try changing the function definition in C++ to accept LPCTSTR and the
P/Invoke definition to use string type for the corresponding parameter

Brian said:
Thanks Alex--

In the first case, I've tried passing the byte array (and many other
variants) but no luck yet. I tested the function by hard coding the
filename (the parameter getting passed) in the eVC++ method, and it works.
Without it, the method is returning a file not found error, which seems to
indicate that it's getting passed incorrectly, since hard coding it within
the DLL works.

In using the byte array, I've tried the following:
<DllImport("myDLL.dll")> Public Shared Function FmodPlay(ByVal filename
As byte(), ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

And in my code, I tried the following;

Dim strFilename As String = "test.mp3"
Dim myByteArray As Byte()
Dim a As New System.Text.UTF8Encoding
myByteArray = a.GetBytes(strFilename)

Tried a few variations off this as well, still getting a file not found. Do
you see anything obvious that's wrong?

Brian



Alex Feinman said:
String would cut it just fine as long as the parameter is LPCWSTR. If you
need to pass char string (ANSI), declare the parameter as byte array
on
the
CF side. If you need to pass a buffer that is to be filled on the unmanaged
side, use StringBuilder type preallocated to the required size

Returning char* (or wchar*) is subject to the same considerations plus one
more thing. Do not return dynamic buffers (allocated with new[]). You can
return pointers allocated using CoTaskMemAlloc or LocalAlloc and use
P/Invoke to free this memory, or if you want to use new, provide a function
that would free memory for you on the unmanaged side

Hi all,

I'm collaborating on a project with another developer, he's the C++ guy,
I'm
the .NET guy, and getting my code to talk to his code is causing some
headaches. I'm hoping some of this is simple.

In the C++ dll, there's a function defined like (chopping off the extern
"c", et. al.):
... int WINAPI Play(char * Filename,int Loop, int Sync)

What is the proper way (VB.NET or C#) to pass in the filename in my
P/Invoke? Right now I've got (realizing the string likely won't cut it):

<DllImport("mydll.dll")> Public Shared Function Play(ByVal
Filename
As
String, ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

Similarly there are functions that return char*, such as (chopping
off
the
extern "c", et. al.):
... char* WINAPI Test();

I've seen a few posts around the net on similar issues using a byte array
or
stringbuilder, but am feeling a tad lost right now...

Thanks for the help!

Brian
 
A

Alex Feinman [MVP]

If you are sure you need char*, use Encoding.Ansi.GetBytes(string) and pass
this as byte[] (the VC++ function should be still declared as char*)

Brian said:
Will do... in the meantime: the dll that this is wrapping needs a char * as
a parameter: how can I convert the LPCTSTR to a char*?

-Brian

Alex Feinman said:
Please try changing the function definition in C++ to accept LPCTSTR and the
P/Invoke definition to use string type for the corresponding parameter
seems
to
indicate that it's getting passed incorrectly, since hard coding it within
the DLL works.

In using the byte array, I've tried the following:
<DllImport("myDLL.dll")> Public Shared Function FmodPlay(ByVal filename
As byte(), ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

And in my code, I tried the following;

Dim strFilename As String = "test.mp3"
Dim myByteArray As Byte()
Dim a As New System.Text.UTF8Encoding
myByteArray = a.GetBytes(strFilename)

Tried a few variations off this as well, still getting a file not
found.
Do
you see anything obvious that's wrong?

Brian



String would cut it just fine as long as the parameter is LPCWSTR.
If
you
need to pass char string (ANSI), declare the parameter as byte array on
the
CF side. If you need to pass a buffer that is to be filled on the
unmanaged
side, use StringBuilder type preallocated to the required size

Returning char* (or wchar*) is subject to the same considerations
plus
one
more thing. Do not return dynamic buffers (allocated with new[]).
You
can
return pointers allocated using CoTaskMemAlloc or LocalAlloc and use
P/Invoke to free this memory, or if you want to use new, provide a
function
that would free memory for you on the unmanaged side

Hi all,

I'm collaborating on a project with another developer, he's the
C++
guy,
I'm
the .NET guy, and getting my code to talk to his code is causing some
headaches. I'm hoping some of this is simple.

In the C++ dll, there's a function defined like (chopping off the extern
"c", et. al.):
... int WINAPI Play(char * Filename,int Loop, int Sync)

What is the proper way (VB.NET or C#) to pass in the filename in my
P/Invoke? Right now I've got (realizing the string likely won't cut
it):

<DllImport("mydll.dll")> Public Shared Function Play(ByVal Filename
As
String, ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

Similarly there are functions that return char*, such as (chopping off
the
extern "c", et. al.):
... char* WINAPI Test();

I've seen a few posts around the net on similar issues using a byte
array
or
stringbuilder, but am feeling a tad lost right now...

Thanks for the help!

Brian
 
B

Brian

Thanks Alex -- yes, this is a wrapper dll, and that method does indeed use a
char*.

As for Encoding.Ansi -- I can't find that anywhere -- in fact I dug around
in System.Text and can find nothing similar... which is why previously I was
doing UTF8, ASCII, etc.

Thanks again,
Brian


Alex Feinman said:
If you are sure you need char*, use Encoding.Ansi.GetBytes(string) and pass
this as byte[] (the VC++ function should be still declared as char*)

Brian said:
Will do... in the meantime: the dll that this is wrapping needs a char
*
as
a parameter: how can I convert the LPCTSTR to a char*?

-Brian

Alex Feinman said:
Please try changing the function definition in C++ to accept LPCTSTR
and
the
P/Invoke definition to use string type for the corresponding parameter

Thanks Alex--

In the first case, I've tried passing the byte array (and many other
variants) but no luck yet. I tested the function by hard coding the
filename (the parameter getting passed) in the eVC++ method, and it works.
Without it, the method is returning a file not found error, which
seems
to
indicate that it's getting passed incorrectly, since hard coding it within
the DLL works.

In using the byte array, I've tried the following:
<DllImport("myDLL.dll")> Public Shared Function FmodPlay(ByVal filename
As byte(), ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

And in my code, I tried the following;

Dim strFilename As String = "test.mp3"
Dim myByteArray As Byte()
Dim a As New System.Text.UTF8Encoding
myByteArray = a.GetBytes(strFilename)

Tried a few variations off this as well, still getting a file not found.
Do
you see anything obvious that's wrong?

Brian



String would cut it just fine as long as the parameter is LPCWSTR. If
you
need to pass char string (ANSI), declare the parameter as byte
array
on
the
CF side. If you need to pass a buffer that is to be filled on the
unmanaged
side, use StringBuilder type preallocated to the required size

Returning char* (or wchar*) is subject to the same considerations plus
one
more thing. Do not return dynamic buffers (allocated with new[]). You
can
return pointers allocated using CoTaskMemAlloc or LocalAlloc and use
P/Invoke to free this memory, or if you want to use new, provide a
function
that would free memory for you on the unmanaged side

Hi all,

I'm collaborating on a project with another developer, he's the C++
guy,
I'm
the .NET guy, and getting my code to talk to his code is causing some
headaches. I'm hoping some of this is simple.

In the C++ dll, there's a function defined like (chopping off the
extern
"c", et. al.):
... int WINAPI Play(char * Filename,int Loop, int Sync)

What is the proper way (VB.NET or C#) to pass in the filename in my
P/Invoke? Right now I've got (realizing the string likely won't cut
it):

<DllImport("mydll.dll")> Public Shared Function Play(ByVal Filename
As
String, ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

Similarly there are functions that return char*, such as
(chopping
off
the
extern "c", et. al.):
... char* WINAPI Test();

I've seen a few posts around the net on similar issues using a byte
array
or
stringbuilder, but am feeling a tad lost right now...

Thanks for the help!

Brian
 
B

Brian

I did try
System.Text.Encoding.Default.GetBytes(strFilename)

Leaving the DLL accepting a char*, passing a byte() from the .NET function.
But no luck.

Brian

Brian said:
Thanks Alex -- yes, this is a wrapper dll, and that method does indeed use a
char*.

As for Encoding.Ansi -- I can't find that anywhere -- in fact I dug around
in System.Text and can find nothing similar... which is why previously I was
doing UTF8, ASCII, etc.

Thanks again,
Brian


Alex Feinman said:
If you are sure you need char*, use Encoding.Ansi.GetBytes(string) and pass
this as byte[] (the VC++ function should be still declared as char*)

Brian said:
Will do... in the meantime: the dll that this is wrapping needs a
char
*
as
a parameter: how can I convert the LPCTSTR to a char*?

-Brian

Please try changing the function definition in C++ to accept LPCTSTR and
the
P/Invoke definition to use string type for the corresponding parameter

Thanks Alex--

In the first case, I've tried passing the byte array (and many other
variants) but no luck yet. I tested the function by hard coding the
filename (the parameter getting passed) in the eVC++ method, and it
works.
Without it, the method is returning a file not found error, which seems
to
indicate that it's getting passed incorrectly, since hard coding it
within
the DLL works.

In using the byte array, I've tried the following:
<DllImport("myDLL.dll")> Public Shared Function FmodPlay(ByVal
filename
As byte(), ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

And in my code, I tried the following;

Dim strFilename As String = "test.mp3"
Dim myByteArray As Byte()
Dim a As New System.Text.UTF8Encoding
myByteArray = a.GetBytes(strFilename)

Tried a few variations off this as well, still getting a file not found.
Do
you see anything obvious that's wrong?

Brian



String would cut it just fine as long as the parameter is
LPCWSTR.
If
you
need to pass char string (ANSI), declare the parameter as byte array
on
the
CF side. If you need to pass a buffer that is to be filled on the
unmanaged
side, use StringBuilder type preallocated to the required size

Returning char* (or wchar*) is subject to the same
considerations
plus
one
more thing. Do not return dynamic buffers (allocated with
new[]).
You
can
return pointers allocated using CoTaskMemAlloc or LocalAlloc and use
P/Invoke to free this memory, or if you want to use new, provide a
function
that would free memory for you on the unmanaged side

Hi all,

I'm collaborating on a project with another developer, he's
the
C++
guy,
I'm
the .NET guy, and getting my code to talk to his code is causing
some
headaches. I'm hoping some of this is simple.

In the C++ dll, there's a function defined like (chopping off the
extern
"c", et. al.):
... int WINAPI Play(char * Filename,int Loop, int Sync)

What is the proper way (VB.NET or C#) to pass in the filename
in
my
P/Invoke? Right now I've got (realizing the string likely
won't
cut
it):

<DllImport("mydll.dll")> Public Shared Function Play(ByVal
Filename
As
String, ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

Similarly there are functions that return char*, such as (chopping
off
the
extern "c", et. al.):
... char* WINAPI Test();

I've seen a few posts around the net on similar issues using a byte
array
or
stringbuilder, but am feeling a tad lost right now...

Thanks for the help!

Brian
 
B

Brian

Hi Alex --

I got it!

I used System.Text.Encoding.Default.GetBytes(strFilename), but for
strFilename, I had to append a terminator -- chr(0)... Never occured to me
that it would be necessary, but it now works... thank you for your help!

Brian


Alex Feinman said:
If you are sure you need char*, use Encoding.Ansi.GetBytes(string) and pass
this as byte[] (the VC++ function should be still declared as char*)

Brian said:
Will do... in the meantime: the dll that this is wrapping needs a char
*
as
a parameter: how can I convert the LPCTSTR to a char*?

-Brian

Alex Feinman said:
Please try changing the function definition in C++ to accept LPCTSTR
and
the
P/Invoke definition to use string type for the corresponding parameter

Thanks Alex--

In the first case, I've tried passing the byte array (and many other
variants) but no luck yet. I tested the function by hard coding the
filename (the parameter getting passed) in the eVC++ method, and it works.
Without it, the method is returning a file not found error, which
seems
to
indicate that it's getting passed incorrectly, since hard coding it within
the DLL works.

In using the byte array, I've tried the following:
<DllImport("myDLL.dll")> Public Shared Function FmodPlay(ByVal filename
As byte(), ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

And in my code, I tried the following;

Dim strFilename As String = "test.mp3"
Dim myByteArray As Byte()
Dim a As New System.Text.UTF8Encoding
myByteArray = a.GetBytes(strFilename)

Tried a few variations off this as well, still getting a file not found.
Do
you see anything obvious that's wrong?

Brian



String would cut it just fine as long as the parameter is LPCWSTR. If
you
need to pass char string (ANSI), declare the parameter as byte
array
on
the
CF side. If you need to pass a buffer that is to be filled on the
unmanaged
side, use StringBuilder type preallocated to the required size

Returning char* (or wchar*) is subject to the same considerations plus
one
more thing. Do not return dynamic buffers (allocated with new[]). You
can
return pointers allocated using CoTaskMemAlloc or LocalAlloc and use
P/Invoke to free this memory, or if you want to use new, provide a
function
that would free memory for you on the unmanaged side

Hi all,

I'm collaborating on a project with another developer, he's the C++
guy,
I'm
the .NET guy, and getting my code to talk to his code is causing some
headaches. I'm hoping some of this is simple.

In the C++ dll, there's a function defined like (chopping off the
extern
"c", et. al.):
... int WINAPI Play(char * Filename,int Loop, int Sync)

What is the proper way (VB.NET or C#) to pass in the filename in my
P/Invoke? Right now I've got (realizing the string likely won't cut
it):

<DllImport("mydll.dll")> Public Shared Function Play(ByVal Filename
As
String, ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

Similarly there are functions that return char*, such as
(chopping
off
the
extern "c", et. al.):
... char* WINAPI Test();

I've seen a few posts around the net on similar issues using a byte
array
or
stringbuilder, but am feeling a tad lost right now...

Thanks for the help!

Brian
 
A

Alex Feinman [MVP]

Sorry, that was ASCII not Ansi

Brian said:
Thanks Alex -- yes, this is a wrapper dll, and that method does indeed use a
char*.

As for Encoding.Ansi -- I can't find that anywhere -- in fact I dug around
in System.Text and can find nothing similar... which is why previously I was
doing UTF8, ASCII, etc.

Thanks again,
Brian


Alex Feinman said:
If you are sure you need char*, use Encoding.Ansi.GetBytes(string) and pass
this as byte[] (the VC++ function should be still declared as char*)

Brian said:
Will do... in the meantime: the dll that this is wrapping needs a
char
*
as
a parameter: how can I convert the LPCTSTR to a char*?

-Brian

Please try changing the function definition in C++ to accept LPCTSTR and
the
P/Invoke definition to use string type for the corresponding parameter

Thanks Alex--

In the first case, I've tried passing the byte array (and many other
variants) but no luck yet. I tested the function by hard coding the
filename (the parameter getting passed) in the eVC++ method, and it
works.
Without it, the method is returning a file not found error, which seems
to
indicate that it's getting passed incorrectly, since hard coding it
within
the DLL works.

In using the byte array, I've tried the following:
<DllImport("myDLL.dll")> Public Shared Function FmodPlay(ByVal
filename
As byte(), ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

And in my code, I tried the following;

Dim strFilename As String = "test.mp3"
Dim myByteArray As Byte()
Dim a As New System.Text.UTF8Encoding
myByteArray = a.GetBytes(strFilename)

Tried a few variations off this as well, still getting a file not found.
Do
you see anything obvious that's wrong?

Brian



String would cut it just fine as long as the parameter is
LPCWSTR.
If
you
need to pass char string (ANSI), declare the parameter as byte array
on
the
CF side. If you need to pass a buffer that is to be filled on the
unmanaged
side, use StringBuilder type preallocated to the required size

Returning char* (or wchar*) is subject to the same
considerations
plus
one
more thing. Do not return dynamic buffers (allocated with
new[]).
You
can
return pointers allocated using CoTaskMemAlloc or LocalAlloc and use
P/Invoke to free this memory, or if you want to use new, provide a
function
that would free memory for you on the unmanaged side

Hi all,

I'm collaborating on a project with another developer, he's
the
C++
guy,
I'm
the .NET guy, and getting my code to talk to his code is causing
some
headaches. I'm hoping some of this is simple.

In the C++ dll, there's a function defined like (chopping off the
extern
"c", et. al.):
... int WINAPI Play(char * Filename,int Loop, int Sync)

What is the proper way (VB.NET or C#) to pass in the filename
in
my
P/Invoke? Right now I've got (realizing the string likely
won't
cut
it):

<DllImport("mydll.dll")> Public Shared Function Play(ByVal
Filename
As
String, ByVal mLoop As Int32, ByVal mSync As Int32) As Int32
End Function

Similarly there are functions that return char*, such as (chopping
off
the
extern "c", et. al.):
... char* WINAPI Test();

I've seen a few posts around the net on similar issues using a byte
array
or
stringbuilder, but am feeling a tad lost right now...

Thanks for the help!

Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top