By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,663 Members | 2,157 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,663 IT Pros & Developers. It's quick & easy.

Need help with importing unmanaged code

P: n/a
Hi, I am trying to figure out how to use unmanaged code using P/Invoke. I
wrote a simple function which takes in 2 buffers (one a byte buffer, one a
char buffer) and copies the contents of the byte buffer into the character
pointer. The code looks like the following:

#include <stdio.h>
#include <stdlib.h>
#include "stdafx.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}

extern "C" __declspec(dllexport)
void ReturnCharPointer(UINT8 *buffer, int buffersize, char *charbuf, int
charbufsize) {
int i =0;
for(i=0; i < charbufsize; i++) {
if(i>=buffersize)
return;
//printf("BYTE %d: %d\r\n",i,buffer[i]);
charbuf[i] = buffer[i];
//printf("CHAR %d: %c\r\n",i,charbuf[i]);
}
}

Now I try to import that function with the following line in a C# project:

[DllImport("DllShell")]
unsafe static extern void ReturnCharPointer(byte *buffer, int buffersize,
char *charbuf, int charbufsize);

I use this in the following function:

unsafe private void ParseBuffer()
{
int a = 100;
int b = 75;
byte[] bytebuf = new byte[a];
char[] charbuf = new char[b];
for(int i =0; i <a; i++)
{
bytebuf[i]= Convert.ToByte(i);
}
fixed(byte *bbuf=bytebuf)
fixed(char *cbuf = charbuf)
ReturnCharPointer(bbuf,a,cbuf,b);
for(int i =0; i < b; i++)
{
Console.Write(charbuf[i] + ", ");
}

}

My problem is the following: I can import and run the code just fine.
However, when the function exits, the data in the character buffer is not
what is expected! The byte buffer contains the numbers 0-99, the character
buffer, whose size is 75 contains the following : [0] = 256, [1] = 770, [2]
= 1284, [3] = 1798.... etc. The rest of the array is incremented at the same
rate until index 37 which contains the value "74". Since 74 should be the
last entry in the buffer, i suspect that the data is somehow being squashed
on the way into or out of the unmanaged C dll. Also I was unable to use
printf in the dll as it threw the following compiler error:
"error C3861: 'printf': identifier not found, even with argument-dependent
lookup"

If anyone has any clue as to what is going on, it would be greatly
appreciated!!

Thanks,
Tim


Nov 15 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a

Hi Timothy,

Normally, there are 2 ways of interop with unmanaged dll, safe way and
unsafe way.
While the unsafe way is not recommanded, because its memory operations are
all not safe.
Here is the safe way of consuming the unmanaged dll:

[DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
static extern void ReturnCharPointer( byte []bytebuf , int buffersize,
IntPtr charbuf, int charbufsize);

int a = 100;
int b = 75;
byte[] bytebuf = new byte[a];
IntPtr charbuf = Marshal.AllocHGlobal(b);

for(int i =0; i <a; i++)
{
bytebuf[i]= Convert.ToByte(i);
}
ReturnCharPointer(bytebuf,a,charbuf,b);

for(int k=0;k<b;k++)
{
Console.WriteLine(Marshal.ReadByte(charbuf,k));
}

In the last for loop, I use Marshal.Read* function to retrieve data from
unmanaged memory. You can also create a char array in managed memory and
use Marshal.Copy method to copy the unmanaged memory to managed memory,
then it will be comfortable to use.

If you still want to use unsafe way to interop the unmanaged dll, you
should alloc the memory from unmanaged memory, but your code alloc from the
managed memory.
You can do like this:
[DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
unsafe static extern void ReturnCharPointer( byte *bytebuf , int
buffersize, char * charbuf, int charbufsize);

int a = 100;
int b = 75;

byte* bytebuf=(byte*)Marshal.AllocCoTaskMem(a);
char* charbuf=(char*)Marshal.AllocCoTaskMem(b);

for(int i =0; i <a; i++)
{
bytebuf[i]= Convert.ToByte(i);
}

ReturnCharPointer( bytebuf,a, charbuf,b);

After ReturnCharPointer method, in the memory window, you can see that the
charbuf is what you want, but if you want to show it out, you should
interop with some umanaged function such as printf, MessageBoxA to show it
out.

Hope this helps,

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: "Timothy Shih" <ts***@sensicast.com>
| Subject: Need help with importing unmanaged code
| Date: Mon, 13 Oct 2003 11:08:15 -0400
| Lines: 78
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| Message-ID: <eN**************@tk2msftngp13.phx.gbl>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: dsl092-093-226.bos1.dsl.speakeasy.net 66.92.93.226
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!tk2msftn gp13.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:190996
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Hi, I am trying to figure out how to use unmanaged code using P/Invoke. I
| wrote a simple function which takes in 2 buffers (one a byte buffer, one a
| char buffer) and copies the contents of the byte buffer into the character
| pointer. The code looks like the following:
|
| #include <stdio.h>
| #include <stdlib.h>
| #include "stdafx.h"
| BOOL APIENTRY DllMain( HANDLE hModule,
| DWORD ul_reason_for_call,
| LPVOID lpReserved
| )
| {
| return TRUE;
| }
|
| extern "C" __declspec(dllexport)
| void ReturnCharPointer(UINT8 *buffer, int buffersize, char *charbuf, int
| charbufsize) {
| int i =0;
| for(i=0; i < charbufsize; i++) {
| if(i>=buffersize)
| return;
| //printf("BYTE %d: %d\r\n",i,buffer[i]);
| charbuf[i] = buffer[i];
| //printf("CHAR %d: %c\r\n",i,charbuf[i]);
| }
| }
|
| Now I try to import that function with the following line in a C# project:
|
| [DllImport("DllShell")]
| unsafe static extern void ReturnCharPointer(byte *buffer, int buffersize,
| char *charbuf, int charbufsize);
|
| I use this in the following function:
|
| unsafe private void ParseBuffer()
| {
| int a = 100;
| int b = 75;
| byte[] bytebuf = new byte[a];
| char[] charbuf = new char[b];
| for(int i =0; i <a; i++)
| {
| bytebuf[i]= Convert.ToByte(i);
| }
| fixed(byte *bbuf=bytebuf)
| fixed(char *cbuf = charbuf)
| ReturnCharPointer(bbuf,a,cbuf,b);
| for(int i =0; i < b; i++)
| {
| Console.Write(charbuf[i] + ", ");
| }
|
| }
|
| My problem is the following: I can import and run the code just fine.
| However, when the function exits, the data in the character buffer is not
| what is expected! The byte buffer contains the numbers 0-99, the character
| buffer, whose size is 75 contains the following : [0] = 256, [1] = 770,
[2]
| = 1284, [3] = 1798.... etc. The rest of the array is incremented at the
same
| rate until index 37 which contains the value "74". Since 74 should be the
| last entry in the buffer, i suspect that the data is somehow being
squashed
| on the way into or out of the unmanaged C dll. Also I was unable to use
| printf in the dll as it threw the following compiler error:
| "error C3861: 'printf': identifier not found, even with argument-dependent
| lookup"
|
| If anyone has any clue as to what is going on, it would be greatly
| appreciated!!
|
| Thanks,
| Tim
|
|
|
|
|

Nov 15 '05 #2

P: n/a

HI Timothy,

On my machine, when I consume the dll, the printf works well and no error
generates.
Btw: In your second printf, you should use %d to show your data, if you use
%c, it will display it as Ascii.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| X-Tomcat-ID: 235590570
| References: <eN**************@tk2msftngp13.phx.gbl>
| MIME-Version: 1.0
| Content-Type: text/plain
| Content-Transfer-Encoding: 7bit
| From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| Organization: Microsoft
| Date: Tue, 14 Oct 2003 09:37:27 GMT
| Subject: RE: Need help with importing unmanaged code
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| Message-ID: <Lq**************@cpmsftngxa06.phx.gbl>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| Lines: 132
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:191149
| NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
|
|
| Hi Timothy,
|
| Normally, there are 2 ways of interop with unmanaged dll, safe way and
| unsafe way.
| While the unsafe way is not recommanded, because its memory operations
are
| all not safe.
| Here is the safe way of consuming the unmanaged dll:
|
| [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| static extern void ReturnCharPointer( byte []bytebuf , int buffersize,
| IntPtr charbuf, int charbufsize);
|
| int a = 100;
| int b = 75;
| byte[] bytebuf = new byte[a];
| IntPtr charbuf = Marshal.AllocHGlobal(b);
|
| for(int i =0; i <a; i++)
| {
| bytebuf[i]= Convert.ToByte(i);
| }
| ReturnCharPointer(bytebuf,a,charbuf,b);
|
| for(int k=0;k<b;k++)
| {
| Console.WriteLine(Marshal.ReadByte(charbuf,k));
| }
|
| In the last for loop, I use Marshal.Read* function to retrieve data from
| unmanaged memory. You can also create a char array in managed memory and
| use Marshal.Copy method to copy the unmanaged memory to managed memory,
| then it will be comfortable to use.
|
| If you still want to use unsafe way to interop the unmanaged dll, you
| should alloc the memory from unmanaged memory, but your code alloc from
the
| managed memory.
| You can do like this:
| [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| unsafe static extern void ReturnCharPointer( byte *bytebuf , int
| buffersize, char * charbuf, int charbufsize);
|
| int a = 100;
| int b = 75;
|
| byte* bytebuf=(byte*)Marshal.AllocCoTaskMem(a);
| char* charbuf=(char*)Marshal.AllocCoTaskMem(b);
|
| for(int i =0; i <a; i++)
| {
| bytebuf[i]= Convert.ToByte(i);
| }
|
| ReturnCharPointer( bytebuf,a, charbuf,b);
|
| After ReturnCharPointer method, in the memory window, you can see that
the
| charbuf is what you want, but if you want to show it out, you should
| interop with some umanaged function such as printf, MessageBoxA to show
it
| out.
|
| Hope this helps,
|
| Best regards,
| Jeffrey Tan
| Microsoft Online Partner Support
| Get Secure! - www.microsoft.com/security
| This posting is provided "as is" with no warranties and confers no rights.
|
| --------------------
| | From: "Timothy Shih" <ts***@sensicast.com>
| | Subject: Need help with importing unmanaged code
| | Date: Mon, 13 Oct 2003 11:08:15 -0400
| | Lines: 78
| | X-Priority: 3
| | X-MSMail-Priority: Normal
| | X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| | Message-ID: <eN**************@tk2msftngp13.phx.gbl>
| | Newsgroups: microsoft.public.dotnet.languages.csharp
| | NNTP-Posting-Host: dsl092-093-226.bos1.dsl.speakeasy.net 66.92.93.226
| | Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!tk2msftn gp13.phx.gbl
| | Xref: cpmsftngxa06.phx.gbl
microsoft.public.dotnet.languages.csharp:190996
| | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| |
| | Hi, I am trying to figure out how to use unmanaged code using P/Invoke.
I
| | wrote a simple function which takes in 2 buffers (one a byte buffer,
one a
| | char buffer) and copies the contents of the byte buffer into the
character
| | pointer. The code looks like the following:
| |
| | #include <stdio.h>
| | #include <stdlib.h>
| | #include "stdafx.h"
| | BOOL APIENTRY DllMain( HANDLE hModule,
| | DWORD ul_reason_for_call,
| | LPVOID lpReserved
| | )
| | {
| | return TRUE;
| | }
| |
| | extern "C" __declspec(dllexport)
| | void ReturnCharPointer(UINT8 *buffer, int buffersize, char *charbuf, int
| | charbufsize) {
| | int i =0;
| | for(i=0; i < charbufsize; i++) {
| | if(i>=buffersize)
| | return;
| | //printf("BYTE %d: %d\r\n",i,buffer[i]);
| | charbuf[i] = buffer[i];
| | //printf("CHAR %d: %c\r\n",i,charbuf[i]);
| | }
| | }
| |
| | Now I try to import that function with the following line in a C#
project:
| |
| | [DllImport("DllShell")]
| | unsafe static extern void ReturnCharPointer(byte *buffer, int
buffersize,
| | char *charbuf, int charbufsize);
| |
| | I use this in the following function:
| |
| | unsafe private void ParseBuffer()
| | {
| | int a = 100;
| | int b = 75;
| | byte[] bytebuf = new byte[a];
| | char[] charbuf = new char[b];
| | for(int i =0; i <a; i++)
| | {
| | bytebuf[i]= Convert.ToByte(i);
| | }
| | fixed(byte *bbuf=bytebuf)
| | fixed(char *cbuf = charbuf)
| | ReturnCharPointer(bbuf,a,cbuf,b);
| | for(int i =0; i < b; i++)
| | {
| | Console.Write(charbuf[i] + ", ");
| | }
| |
| | }
| |
| | My problem is the following: I can import and run the code just fine.
| | However, when the function exits, the data in the character buffer is
not
| | what is expected! The byte buffer contains the numbers 0-99, the
character
| | buffer, whose size is 75 contains the following : [0] = 256, [1] = 770,
| [2]
| | = 1284, [3] = 1798.... etc. The rest of the array is incremented at the
| same
| | rate until index 37 which contains the value "74". Since 74 should be
the
| | last entry in the buffer, i suspect that the data is somehow being
| squashed
| | on the way into or out of the unmanaged C dll. Also I was unable to use
| | printf in the dll as it threw the following compiler error:
| | "error C3861: 'printf': identifier not found, even with
argument-dependent
| | lookup"
| |
| | If anyone has any clue as to what is going on, it would be greatly
| | appreciated!!
| |
| | Thanks,
| | Tim
| |
| |
| |
| |
| |
|
|

Nov 15 '05 #3

P: n/a

Hi Timothy,

You can also alloc your memory from managed memory, but you should marshal
it correctly.
Sample code like this:
[DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
static extern void
ReturnCharPointer([In,Out,MarshalAs(UnmanagedType.LPArray,
SizeParamIndex=1)] byte []bytebuf,int
buffersize,[In,Out,MarshalAs(UnmanagedType.LPArray, SizeParamIndex=3)] char
[]charbuf,int charbufsize);

int a = 100;
int b = 75;
byte[] bytebuf = new byte[a];
char[] charbuf = new char[b];
for(int i =0; i <a; i++)
{
bytebuf[i]= Convert.ToByte(i);
}

ReturnCharPointer( bytebuf,a, charbuf,b);
for(int k=0; k< b;k++)
{
Console.Write(Convert.ToInt32(charbuf[k]) + ", ");
}

It works well on my machine, if you still have any question, please feel
free to let me know.

Btw: I think the strange display of your code is because in C# a char is
2-bytes, while in C/C++ a char is 1-byte long. You¡¯ve got an ASCII/UNICODE
mismatch when you are passing in the char* from C#.

Hope all these help

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| X-Tomcat-ID: 243569578
| References: <eN**************@tk2msftngp13.phx.gbl>
<Lq**************@cpmsftngxa06.phx.gbl>
| MIME-Version: 1.0
| Content-Type: text/plain
| Content-Transfer-Encoding: 7bit
| From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| Organization: Microsoft
| Date: Tue, 14 Oct 2003 09:58:58 GMT
| Subject: RE: Need help with importing unmanaged code
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| Message-ID: <Da**************@cpmsftngxa06.phx.gbl>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| Lines: 169
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:191157
| NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
|
|
| HI Timothy,
|
| On my machine, when I consume the dll, the printf works well and no error
| generates.
| Btw: In your second printf, you should use %d to show your data, if you
use
| %c, it will display it as Ascii.
|
| Best regards,
| Jeffrey Tan
| Microsoft Online Partner Support
| Get Secure! - www.microsoft.com/security
| This posting is provided "as is" with no warranties and confers no rights.
|
| --------------------
| | X-Tomcat-ID: 235590570
| | References: <eN**************@tk2msftngp13.phx.gbl>
| | MIME-Version: 1.0
| | Content-Type: text/plain
| | Content-Transfer-Encoding: 7bit
| | From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| | Organization: Microsoft
| | Date: Tue, 14 Oct 2003 09:37:27 GMT
| | Subject: RE: Need help with importing unmanaged code
| | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| | Message-ID: <Lq**************@cpmsftngxa06.phx.gbl>
| | Newsgroups: microsoft.public.dotnet.languages.csharp
| | Lines: 132
| | Path: cpmsftngxa06.phx.gbl
| | Xref: cpmsftngxa06.phx.gbl
microsoft.public.dotnet.languages.csharp:191149
| | NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
| |
| |
| | Hi Timothy,
| |
| | Normally, there are 2 ways of interop with unmanaged dll, safe way and
| | unsafe way.
| | While the unsafe way is not recommanded, because its memory operations
| are
| | all not safe.
| | Here is the safe way of consuming the unmanaged dll:
| |
| | [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| | static extern void ReturnCharPointer( byte []bytebuf , int buffersize,

| | IntPtr charbuf, int charbufsize);
| |
| | int a = 100;
| | int b = 75;
| | byte[] bytebuf = new byte[a];
| | IntPtr charbuf = Marshal.AllocHGlobal(b);
| |
| | for(int i =0; i <a; i++)
| | {
| | bytebuf[i]= Convert.ToByte(i);
| | }
| | ReturnCharPointer(bytebuf,a,charbuf,b);
| |
| | for(int k=0;k<b;k++)
| | {
| | Console.WriteLine(Marshal.ReadByte(charbuf,k));
| | }
| |
| | In the last for loop, I use Marshal.Read* function to retrieve data
from
| | unmanaged memory. You can also create a char array in managed memory
and
| | use Marshal.Copy method to copy the unmanaged memory to managed memory,
| | then it will be comfortable to use.
| |
| | If you still want to use unsafe way to interop the unmanaged dll, you
| | should alloc the memory from unmanaged memory, but your code alloc from
| the
| | managed memory.
| | You can do like this:
| | [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| | unsafe static extern void ReturnCharPointer( byte *bytebuf , int
| | buffersize, char * charbuf, int charbufsize);
| |
| | int a = 100;
| | int b = 75;
| |
| | byte* bytebuf=(byte*)Marshal.AllocCoTaskMem(a);
| | char* charbuf=(char*)Marshal.AllocCoTaskMem(b);
| |
| | for(int i =0; i <a; i++)
| | {
| | bytebuf[i]= Convert.ToByte(i);
| | }
| |
| | ReturnCharPointer( bytebuf,a, charbuf,b);
| |
| | After ReturnCharPointer method, in the memory window, you can see that
| the
| | charbuf is what you want, but if you want to show it out, you should
| | interop with some umanaged function such as printf, MessageBoxA to show
| it
| | out.
| |
| | Hope this helps,
| |
| | Best regards,
| | Jeffrey Tan
| | Microsoft Online Partner Support
| | Get Secure! - www.microsoft.com/security
| | This posting is provided "as is" with no warranties and confers no
rights.
| |
| | --------------------
| | | From: "Timothy Shih" <ts***@sensicast.com>
| | | Subject: Need help with importing unmanaged code
| | | Date: Mon, 13 Oct 2003 11:08:15 -0400
| | | Lines: 78
| | | X-Priority: 3
| | | X-MSMail-Priority: Normal
| | | X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| | | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| | | Message-ID: <eN**************@tk2msftngp13.phx.gbl>
| | | Newsgroups: microsoft.public.dotnet.languages.csharp
| | | NNTP-Posting-Host: dsl092-093-226.bos1.dsl.speakeasy.net 66.92.93.226
| | | Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!tk2msftn gp13.phx.gbl
| | | Xref: cpmsftngxa06.phx.gbl
| microsoft.public.dotnet.languages.csharp:190996
| | | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| | |
| | | Hi, I am trying to figure out how to use unmanaged code using
P/Invoke.
| I
| | | wrote a simple function which takes in 2 buffers (one a byte buffer,
| one a
| | | char buffer) and copies the contents of the byte buffer into the
| character
| | | pointer. The code looks like the following:
| | |
| | | #include <stdio.h>
| | | #include <stdlib.h>
| | | #include "stdafx.h"
| | | BOOL APIENTRY DllMain( HANDLE hModule,
| | | DWORD ul_reason_for_call,
| | | LPVOID lpReserved
| | | )
| | | {
| | | return TRUE;
| | | }
| | |
| | | extern "C" __declspec(dllexport)
| | | void ReturnCharPointer(UINT8 *buffer, int buffersize, char *charbuf,
int
| | | charbufsize) {
| | | int i =0;
| | | for(i=0; i < charbufsize; i++) {
| | | if(i>=buffersize)
| | | return;
| | | //printf("BYTE %d: %d\r\n",i,buffer[i]);
| | | charbuf[i] = buffer[i];
| | | //printf("CHAR %d: %c\r\n",i,charbuf[i]);
| | | }
| | | }
| | |
| | | Now I try to import that function with the following line in a C#
| project:
| | |
| | | [DllImport("DllShell")]
| | | unsafe static extern void ReturnCharPointer(byte *buffer, int
| buffersize,
| | | char *charbuf, int charbufsize);
| | |
| | | I use this in the following function:
| | |
| | | unsafe private void ParseBuffer()
| | | {
| | | int a = 100;
| | | int b = 75;
| | | byte[] bytebuf = new byte[a];
| | | char[] charbuf = new char[b];
| | | for(int i =0; i <a; i++)
| | | {
| | | bytebuf[i]= Convert.ToByte(i);
| | | }
| | | fixed(byte *bbuf=bytebuf)
| | | fixed(char *cbuf = charbuf)
| | | ReturnCharPointer(bbuf,a,cbuf,b);
| | | for(int i =0; i < b; i++)
| | | {
| | | Console.Write(charbuf[i] + ", ");
| | | }
| | |
| | | }
| | |
| | | My problem is the following: I can import and run the code just fine.
| | | However, when the function exits, the data in the character buffer is
| not
| | | what is expected! The byte buffer contains the numbers 0-99, the
| character
| | | buffer, whose size is 75 contains the following : [0] = 256, [1] =
770,
| | [2]
| | | = 1284, [3] = 1798.... etc. The rest of the array is incremented at
the
| | same
| | | rate until index 37 which contains the value "74". Since 74 should be
| the
| | | last entry in the buffer, i suspect that the data is somehow being
| | squashed
| | | on the way into or out of the unmanaged C dll. Also I was unable to
use
| | | printf in the dll as it threw the following compiler error:
| | | "error C3861: 'printf': identifier not found, even with
| argument-dependent
| | | lookup"
| | |
| | | If anyone has any clue as to what is going on, it would be greatly
| | | appreciated!!
| | |
| | | Thanks,
| | | Tim
| | |
| | |
| | |
| | |
| | |
| |
| |
|
|

Nov 15 '05 #4

P: n/a
Yep, that was the problem! Thanks a lot for your help. Also, I am still
unable to compile with printf, sprintf or fprintf, even though I have
#included stdio.h. Do you have any idea why I can't use these functions?

Thanks again!
Tim
""Jeffrey Tan[MSFT]"" <v-*****@online.microsoft.com> wrote in message
news:El**************@cpmsftngxa06.phx.gbl...

Hi Timothy,

You can also alloc your memory from managed memory, but you should marshal
it correctly.
Sample code like this:
[DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
static extern void
ReturnCharPointer([In,Out,MarshalAs(UnmanagedType.LPArray,
SizeParamIndex=1)] byte []bytebuf,int
buffersize,[In,Out,MarshalAs(UnmanagedType.LPArray, SizeParamIndex=3)] char []charbuf,int charbufsize);

int a = 100;
int b = 75;
byte[] bytebuf = new byte[a];
char[] charbuf = new char[b];
for(int i =0; i <a; i++)
{
bytebuf[i]= Convert.ToByte(i);
}

ReturnCharPointer( bytebuf,a, charbuf,b);
for(int k=0; k< b;k++)
{
Console.Write(Convert.ToInt32(charbuf[k]) + ", ");
}

It works well on my machine, if you still have any question, please feel
free to let me know.

Btw: I think the strange display of your code is because in C# a char is
2-bytes, while in C/C++ a char is 1-byte long. You¡¯ve got an ASCII/UNICODE mismatch when you are passing in the char* from C#.

Hope all these help

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| X-Tomcat-ID: 243569578
| References: <eN**************@tk2msftngp13.phx.gbl>
<Lq**************@cpmsftngxa06.phx.gbl>
| MIME-Version: 1.0
| Content-Type: text/plain
| Content-Transfer-Encoding: 7bit
| From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| Organization: Microsoft
| Date: Tue, 14 Oct 2003 09:58:58 GMT
| Subject: RE: Need help with importing unmanaged code
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| Message-ID: <Da**************@cpmsftngxa06.phx.gbl>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| Lines: 169
| Path: cpmsftngxa06.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:191157 | NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
|
|
| HI Timothy,
|
| On my machine, when I consume the dll, the printf works well and no error | generates.
| Btw: In your second printf, you should use %d to show your data, if you
use
| %c, it will display it as Ascii.
|
| Best regards,
| Jeffrey Tan
| Microsoft Online Partner Support
| Get Secure! - www.microsoft.com/security
| This posting is provided "as is" with no warranties and confers no rights. |
| --------------------
| | X-Tomcat-ID: 235590570
| | References: <eN**************@tk2msftngp13.phx.gbl>
| | MIME-Version: 1.0
| | Content-Type: text/plain
| | Content-Transfer-Encoding: 7bit
| | From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| | Organization: Microsoft
| | Date: Tue, 14 Oct 2003 09:37:27 GMT
| | Subject: RE: Need help with importing unmanaged code
| | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| | Message-ID: <Lq**************@cpmsftngxa06.phx.gbl>
| | Newsgroups: microsoft.public.dotnet.languages.csharp
| | Lines: 132
| | Path: cpmsftngxa06.phx.gbl
| | Xref: cpmsftngxa06.phx.gbl
microsoft.public.dotnet.languages.csharp:191149
| | NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
| |
| |
| | Hi Timothy,
| |
| | Normally, there are 2 ways of interop with unmanaged dll, safe way and
| | unsafe way.
| | While the unsafe way is not recommanded, because its memory operations
| are
| | all not safe.
| | Here is the safe way of consuming the unmanaged dll:
| |
| | [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| | static extern void ReturnCharPointer( byte []bytebuf , int buffersize,

| | IntPtr charbuf, int charbufsize);
| |
| | int a = 100;
| | int b = 75;
| | byte[] bytebuf = new byte[a];
| | IntPtr charbuf = Marshal.AllocHGlobal(b);
| |
| | for(int i =0; i <a; i++)
| | {
| | bytebuf[i]= Convert.ToByte(i);
| | }
| | ReturnCharPointer(bytebuf,a,charbuf,b);
| |
| | for(int k=0;k<b;k++)
| | {
| | Console.WriteLine(Marshal.ReadByte(charbuf,k));
| | }
| |
| | In the last for loop, I use Marshal.Read* function to retrieve data
from
| | unmanaged memory. You can also create a char array in managed memory
and
| | use Marshal.Copy method to copy the unmanaged memory to managed memory, | | then it will be comfortable to use.
| |
| | If you still want to use unsafe way to interop the unmanaged dll, you
| | should alloc the memory from unmanaged memory, but your code alloc from | the
| | managed memory.
| | You can do like this:
| | [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| | unsafe static extern void ReturnCharPointer( byte *bytebuf , int
| | buffersize, char * charbuf, int charbufsize);
| |
| | int a = 100;
| | int b = 75;
| |
| | byte* bytebuf=(byte*)Marshal.AllocCoTaskMem(a);
| | char* charbuf=(char*)Marshal.AllocCoTaskMem(b);
| |
| | for(int i =0; i <a; i++)
| | {
| | bytebuf[i]= Convert.ToByte(i);
| | }
| |
| | ReturnCharPointer( bytebuf,a, charbuf,b);
| |
| | After ReturnCharPointer method, in the memory window, you can see that
| the
| | charbuf is what you want, but if you want to show it out, you should
| | interop with some umanaged function such as printf, MessageBoxA to show | it
| | out.
| |
| | Hope this helps,
| |
| | Best regards,
| | Jeffrey Tan
| | Microsoft Online Partner Support
| | Get Secure! - www.microsoft.com/security
| | This posting is provided "as is" with no warranties and confers no
rights.
| |
| | --------------------
| | | From: "Timothy Shih" <ts***@sensicast.com>
| | | Subject: Need help with importing unmanaged code
| | | Date: Mon, 13 Oct 2003 11:08:15 -0400
| | | Lines: 78
| | | X-Priority: 3
| | | X-MSMail-Priority: Normal
| | | X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| | | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| | | Message-ID: <eN**************@tk2msftngp13.phx.gbl>
| | | Newsgroups: microsoft.public.dotnet.languages.csharp
| | | NNTP-Posting-Host: dsl092-093-226.bos1.dsl.speakeasy.net 66.92.93.226 | | | Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!tk2msftn gp13.phx.gbl
| | | Xref: cpmsftngxa06.phx.gbl
| microsoft.public.dotnet.languages.csharp:190996
| | | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| | |
| | | Hi, I am trying to figure out how to use unmanaged code using
P/Invoke.
| I
| | | wrote a simple function which takes in 2 buffers (one a byte buffer,
| one a
| | | char buffer) and copies the contents of the byte buffer into the
| character
| | | pointer. The code looks like the following:
| | |
| | | #include <stdio.h>
| | | #include <stdlib.h>
| | | #include "stdafx.h"
| | | BOOL APIENTRY DllMain( HANDLE hModule,
| | | DWORD ul_reason_for_call,
| | | LPVOID lpReserved
| | | )
| | | {
| | | return TRUE;
| | | }
| | |
| | | extern "C" __declspec(dllexport)
| | | void ReturnCharPointer(UINT8 *buffer, int buffersize, char *charbuf,
int
| | | charbufsize) {
| | | int i =0;
| | | for(i=0; i < charbufsize; i++) {
| | | if(i>=buffersize)
| | | return;
| | | //printf("BYTE %d: %d\r\n",i,buffer[i]);
| | | charbuf[i] = buffer[i];
| | | //printf("CHAR %d: %c\r\n",i,charbuf[i]);
| | | }
| | | }
| | |
| | | Now I try to import that function with the following line in a C#
| project:
| | |
| | | [DllImport("DllShell")]
| | | unsafe static extern void ReturnCharPointer(byte *buffer, int
| buffersize,
| | | char *charbuf, int charbufsize);
| | |
| | | I use this in the following function:
| | |
| | | unsafe private void ParseBuffer()
| | | {
| | | int a = 100;
| | | int b = 75;
| | | byte[] bytebuf = new byte[a];
| | | char[] charbuf = new char[b];
| | | for(int i =0; i <a; i++)
| | | {
| | | bytebuf[i]= Convert.ToByte(i);
| | | }
| | | fixed(byte *bbuf=bytebuf)
| | | fixed(char *cbuf = charbuf)
| | | ReturnCharPointer(bbuf,a,cbuf,b);
| | | for(int i =0; i < b; i++)
| | | {
| | | Console.Write(charbuf[i] + ", ");
| | | }
| | |
| | | }
| | |
| | | My problem is the following: I can import and run the code just fine. | | | However, when the function exits, the data in the character buffer is | not
| | | what is expected! The byte buffer contains the numbers 0-99, the
| character
| | | buffer, whose size is 75 contains the following : [0] = 256, [1] =
770,
| | [2]
| | | = 1284, [3] = 1798.... etc. The rest of the array is incremented at
the
| | same
| | | rate until index 37 which contains the value "74". Since 74 should be | the
| | | last entry in the buffer, i suspect that the data is somehow being
| | squashed
| | | on the way into or out of the unmanaged C dll. Also I was unable to
use
| | | printf in the dll as it threw the following compiler error:
| | | "error C3861: 'printf': identifier not found, even with
| argument-dependent
| | | lookup"
| | |
| | | If anyone has any clue as to what is going on, it would be greatly
| | | appreciated!!
| | |
| | | Thanks,
| | | Tim
| | |
| | |
| | |
| | |
| | |
| |
| |
|
|

Nov 15 '05 #5

P: n/a

Hi Timothy,

I am glad my research does make sence to you.
For your dll problem, I think you can try to create a new dll project as
"Win32 Dynammic-Link Library" type.
And paste your code, but replace your {#include "stdafx.h"} with {#include
<windows.h>}, I did this and it works well on my machine.

If it still do not work, you can try to create a win32 executive
application to find if this printf generates error.

Hope this helps,

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: "Timothy Shih" <ts***@sensicast.com>
| References: <eN**************@tk2msftngp13.phx.gbl>
<Lq**************@cpmsftngxa06.phx.gbl>
<Da**************@cpmsftngxa06.phx.gbl>
<El**************@cpmsftngxa06.phx.gbl>
| Subject: Re: Need help with importing unmanaged code
| Date: Fri, 17 Oct 2003 14:34:14 -0400
| Lines: 314
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| Message-ID: <Od**************@TK2MSFTNGP09.phx.gbl>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: dsl092-093-226.bos1.dsl.speakeasy.net 66.92.93.226
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTN GP09.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:192165
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Yep, that was the problem! Thanks a lot for your help. Also, I am still
| unable to compile with printf, sprintf or fprintf, even though I have
| #included stdio.h. Do you have any idea why I can't use these functions?
|
| Thanks again!
| Tim
|
|
| ""Jeffrey Tan[MSFT]"" <v-*****@online.microsoft.com> wrote in message
| news:El**************@cpmsftngxa06.phx.gbl...
| >
| > Hi Timothy,
| >
| > You can also alloc your memory from managed memory, but you should
marshal
| > it correctly.
| > Sample code like this:
| > [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| > static extern void
| > ReturnCharPointer([In,Out,MarshalAs(UnmanagedType.LPArray,
| > SizeParamIndex=1)] byte []bytebuf,int
| > buffersize,[In,Out,MarshalAs(UnmanagedType.LPArray, SizeParamIndex=3)]
| char
| > []charbuf,int charbufsize);
| >
| > int a = 100;
| > int b = 75;
| > byte[] bytebuf = new byte[a];
| > char[] charbuf = new char[b];
| > for(int i =0; i <a; i++)
| > {
| > bytebuf[i]= Convert.ToByte(i);
| > }
| >
| > ReturnCharPointer( bytebuf,a, charbuf,b);
| > for(int k=0; k< b;k++)
| > {
| > Console.Write(Convert.ToInt32(charbuf[k]) + ", ");
| > }
| >
| > It works well on my machine, if you still have any question, please feel
| > free to let me know.
| >
| > Btw: I think the strange display of your code is because in C# a char is
| > 2-bytes, while in C/C++ a char is 1-byte long. You¡¯ve got an
| ASCII/UNICODE
| > mismatch when you are passing in the char* from C#.
| >
| > Hope all these help
| >
| > Best regards,
| > Jeffrey Tan
| > Microsoft Online Partner Support
| > Get Secure! - www.microsoft.com/security
| > This posting is provided "as is" with no warranties and confers no
rights.
| >
| > --------------------
| > | X-Tomcat-ID: 243569578
| > | References: <eN**************@tk2msftngp13.phx.gbl>
| > <Lq**************@cpmsftngxa06.phx.gbl>
| > | MIME-Version: 1.0
| > | Content-Type: text/plain
| > | Content-Transfer-Encoding: 7bit
| > | From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| > | Organization: Microsoft
| > | Date: Tue, 14 Oct 2003 09:58:58 GMT
| > | Subject: RE: Need help with importing unmanaged code
| > | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| > | Message-ID: <Da**************@cpmsftngxa06.phx.gbl>
| > | Newsgroups: microsoft.public.dotnet.languages.csharp
| > | Lines: 169
| > | Path: cpmsftngxa06.phx.gbl
| > | Xref: cpmsftngxa06.phx.gbl
| microsoft.public.dotnet.languages.csharp:191157
| > | NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
| > |
| > |
| > | HI Timothy,
| > |
| > | On my machine, when I consume the dll, the printf works well and no
| error
| > | generates.
| > | Btw: In your second printf, you should use %d to show your data, if
you
| > use
| > | %c, it will display it as Ascii.
| > |
| > | Best regards,
| > | Jeffrey Tan
| > | Microsoft Online Partner Support
| > | Get Secure! - www.microsoft.com/security
| > | This posting is provided "as is" with no warranties and confers no
| rights.
| > |
| > | --------------------
| > | | X-Tomcat-ID: 235590570
| > | | References: <eN**************@tk2msftngp13.phx.gbl>
| > | | MIME-Version: 1.0
| > | | Content-Type: text/plain
| > | | Content-Transfer-Encoding: 7bit
| > | | From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| > | | Organization: Microsoft
| > | | Date: Tue, 14 Oct 2003 09:37:27 GMT
| > | | Subject: RE: Need help with importing unmanaged code
| > | | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| > | | Message-ID: <Lq**************@cpmsftngxa06.phx.gbl>
| > | | Newsgroups: microsoft.public.dotnet.languages.csharp
| > | | Lines: 132
| > | | Path: cpmsftngxa06.phx.gbl
| > | | Xref: cpmsftngxa06.phx.gbl
| > microsoft.public.dotnet.languages.csharp:191149
| > | | NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
| > | |
| > | |
| > | | Hi Timothy,
| > | |
| > | | Normally, there are 2 ways of interop with unmanaged dll, safe way
and
| > | | unsafe way.
| > | | While the unsafe way is not recommanded, because its memory
operations
| > | are
| > | | all not safe.
| > | | Here is the safe way of consuming the unmanaged dll:
| > | |
| > | | [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| > | | static extern void ReturnCharPointer( byte []bytebuf , int
buffersize,
| >
| > | | IntPtr charbuf, int charbufsize);
| > | |
| > | | int a = 100;
| > | | int b = 75;
| > | | byte[] bytebuf = new byte[a];
| > | | IntPtr charbuf = Marshal.AllocHGlobal(b);
| > | |
| > | | for(int i =0; i <a; i++)
| > | | {
| > | | bytebuf[i]= Convert.ToByte(i);
| > | | }
| > | | ReturnCharPointer(bytebuf,a,charbuf,b);
| > | |
| > | | for(int k=0;k<b;k++)
| > | | {
| > | | Console.WriteLine(Marshal.ReadByte(charbuf,k));
| > | | }
| > | |
| > | | In the last for loop, I use Marshal.Read* function to retrieve data
| > from
| > | | unmanaged memory. You can also create a char array in managed memory
| > and
| > | | use Marshal.Copy method to copy the unmanaged memory to managed
| memory,
| > | | then it will be comfortable to use.
| > | |
| > | | If you still want to use unsafe way to interop the unmanaged dll,
you
| > | | should alloc the memory from unmanaged memory, but your code alloc
| from
| > | the
| > | | managed memory.
| > | | You can do like this:
| > | | [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| > | | unsafe static extern void ReturnCharPointer( byte *bytebuf , int
| > | | buffersize, char * charbuf, int charbufsize);
| > | |
| > | | int a = 100;
| > | | int b = 75;
| > | |
| > | | byte* bytebuf=(byte*)Marshal.AllocCoTaskMem(a);
| > | | char* charbuf=(char*)Marshal.AllocCoTaskMem(b);
| > | |
| > | | for(int i =0; i <a; i++)
| > | | {
| > | | bytebuf[i]= Convert.ToByte(i);
| > | | }
| > | |
| > | | ReturnCharPointer( bytebuf,a, charbuf,b);
| > | |
| > | | After ReturnCharPointer method, in the memory window, you can see
that
| > | the
| > | | charbuf is what you want, but if you want to show it out, you should
| > | | interop with some umanaged function such as printf, MessageBoxA to
| show
| > | it
| > | | out.
| > | |
| > | | Hope this helps,
| > | |
| > | | Best regards,
| > | | Jeffrey Tan
| > | | Microsoft Online Partner Support
| > | | Get Secure! - www.microsoft.com/security
| > | | This posting is provided "as is" with no warranties and confers no
| > rights.
| > | |
| > | | --------------------
| > | | | From: "Timothy Shih" <ts***@sensicast.com>
| > | | | Subject: Need help with importing unmanaged code
| > | | | Date: Mon, 13 Oct 2003 11:08:15 -0400
| > | | | Lines: 78
| > | | | X-Priority: 3
| > | | | X-MSMail-Priority: Normal
| > | | | X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| > | | | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| > | | | Message-ID: <eN**************@tk2msftngp13.phx.gbl>
| > | | | Newsgroups: microsoft.public.dotnet.languages.csharp
| > | | | NNTP-Posting-Host: dsl092-093-226.bos1.dsl.speakeasy.net
| 66.92.93.226
| > | | | Path:
cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!tk2msftn gp13.phx.gbl
| > | | | Xref: cpmsftngxa06.phx.gbl
| > | microsoft.public.dotnet.languages.csharp:190996
| > | | | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| > | | |
| > | | | Hi, I am trying to figure out how to use unmanaged code using
| > P/Invoke.
| > | I
| > | | | wrote a simple function which takes in 2 buffers (one a byte
buffer,
| > | one a
| > | | | char buffer) and copies the contents of the byte buffer into the
| > | character
| > | | | pointer. The code looks like the following:
| > | | |
| > | | | #include <stdio.h>
| > | | | #include <stdlib.h>
| > | | | #include "stdafx.h"
| > | | | BOOL APIENTRY DllMain( HANDLE hModule,
| > | | | DWORD ul_reason_for_call,
| > | | | LPVOID lpReserved
| > | | | )
| > | | | {
| > | | | return TRUE;
| > | | | }
| > | | |
| > | | | extern "C" __declspec(dllexport)
| > | | | void ReturnCharPointer(UINT8 *buffer, int buffersize, char
*charbuf,
| > int
| > | | | charbufsize) {
| > | | | int i =0;
| > | | | for(i=0; i < charbufsize; i++) {
| > | | | if(i>=buffersize)
| > | | | return;
| > | | | //printf("BYTE %d: %d\r\n",i,buffer[i]);
| > | | | charbuf[i] = buffer[i];
| > | | | //printf("CHAR %d: %c\r\n",i,charbuf[i]);
| > | | | }
| > | | | }
| > | | |
| > | | | Now I try to import that function with the following line in a C#
| > | project:
| > | | |
| > | | | [DllImport("DllShell")]
| > | | | unsafe static extern void ReturnCharPointer(byte *buffer, int
| > | buffersize,
| > | | | char *charbuf, int charbufsize);
| > | | |
| > | | | I use this in the following function:
| > | | |
| > | | | unsafe private void ParseBuffer()
| > | | | {
| > | | | int a = 100;
| > | | | int b = 75;
| > | | | byte[] bytebuf = new byte[a];
| > | | | char[] charbuf = new char[b];
| > | | | for(int i =0; i <a; i++)
| > | | | {
| > | | | bytebuf[i]= Convert.ToByte(i);
| > | | | }
| > | | | fixed(byte *bbuf=bytebuf)
| > | | | fixed(char *cbuf = charbuf)
| > | | | ReturnCharPointer(bbuf,a,cbuf,b);
| > | | | for(int i =0; i < b; i++)
| > | | | {
| > | | | Console.Write(charbuf[i] + ", ");
| > | | | }
| > | | |
| > | | | }
| > | | |
| > | | | My problem is the following: I can import and run the code just
| fine.
| > | | | However, when the function exits, the data in the character buffer
| is
| > | not
| > | | | what is expected! The byte buffer contains the numbers 0-99, the
| > | character
| > | | | buffer, whose size is 75 contains the following : [0] = 256, [1] =
| > 770,
| > | | [2]
| > | | | = 1284, [3] = 1798.... etc. The rest of the array is incremented
at
| > the
| > | | same
| > | | | rate until index 37 which contains the value "74". Since 74 should
| be
| > | the
| > | | | last entry in the buffer, i suspect that the data is somehow being
| > | | squashed
| > | | | on the way into or out of the unmanaged C dll. Also I was unable
to
| > use
| > | | | printf in the dll as it threw the following compiler error:
| > | | | "error C3861: 'printf': identifier not found, even with
| > | argument-dependent
| > | | | lookup"
| > | | |
| > | | | If anyone has any clue as to what is going on, it would be greatly
| > | | | appreciated!!
| > | | |
| > | | | Thanks,
| > | | | Tim
| > | | |
| > | | |
| > | | |
| > | | |
| > | | |
| > | |
| > | |
| > |
| > |
| >
|
|
|

Nov 15 '05 #6

P: n/a

Hi Timothy,

Has your problem been resolved?
If it still does not work, please feel free to let me know.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: "Timothy Shih" <ts***@sensicast.com>
| References: <eN**************@tk2msftngp13.phx.gbl>
<Lq**************@cpmsftngxa06.phx.gbl>
<Da**************@cpmsftngxa06.phx.gbl>
<El**************@cpmsftngxa06.phx.gbl>
| Subject: Re: Need help with importing unmanaged code
| Date: Fri, 17 Oct 2003 14:34:14 -0400
| Lines: 314
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| Message-ID: <Od**************@TK2MSFTNGP09.phx.gbl>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: dsl092-093-226.bos1.dsl.speakeasy.net 66.92.93.226
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTN GP09.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:192165
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Yep, that was the problem! Thanks a lot for your help. Also, I am still
| unable to compile with printf, sprintf or fprintf, even though I have
| #included stdio.h. Do you have any idea why I can't use these functions?
|
| Thanks again!
| Tim
|
|
| ""Jeffrey Tan[MSFT]"" <v-*****@online.microsoft.com> wrote in message
| news:El**************@cpmsftngxa06.phx.gbl...
| >
| > Hi Timothy,
| >
| > You can also alloc your memory from managed memory, but you should
marshal
| > it correctly.
| > Sample code like this:
| > [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| > static extern void
| > ReturnCharPointer([In,Out,MarshalAs(UnmanagedType.LPArray,
| > SizeParamIndex=1)] byte []bytebuf,int
| > buffersize,[In,Out,MarshalAs(UnmanagedType.LPArray, SizeParamIndex=3)]
| char
| > []charbuf,int charbufsize);
| >
| > int a = 100;
| > int b = 75;
| > byte[] bytebuf = new byte[a];
| > char[] charbuf = new char[b];
| > for(int i =0; i <a; i++)
| > {
| > bytebuf[i]= Convert.ToByte(i);
| > }
| >
| > ReturnCharPointer( bytebuf,a, charbuf,b);
| > for(int k=0; k< b;k++)
| > {
| > Console.Write(Convert.ToInt32(charbuf[k]) + ", ");
| > }
| >
| > It works well on my machine, if you still have any question, please feel
| > free to let me know.
| >
| > Btw: I think the strange display of your code is because in C# a char is
| > 2-bytes, while in C/C++ a char is 1-byte long. You¡¯ve got an
| ASCII/UNICODE
| > mismatch when you are passing in the char* from C#.
| >
| > Hope all these help
| >
| > Best regards,
| > Jeffrey Tan
| > Microsoft Online Partner Support
| > Get Secure! - www.microsoft.com/security
| > This posting is provided "as is" with no warranties and confers no
rights.
| >
| > --------------------
| > | X-Tomcat-ID: 243569578
| > | References: <eN**************@tk2msftngp13.phx.gbl>
| > <Lq**************@cpmsftngxa06.phx.gbl>
| > | MIME-Version: 1.0
| > | Content-Type: text/plain
| > | Content-Transfer-Encoding: 7bit
| > | From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| > | Organization: Microsoft
| > | Date: Tue, 14 Oct 2003 09:58:58 GMT
| > | Subject: RE: Need help with importing unmanaged code
| > | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| > | Message-ID: <Da**************@cpmsftngxa06.phx.gbl>
| > | Newsgroups: microsoft.public.dotnet.languages.csharp
| > | Lines: 169
| > | Path: cpmsftngxa06.phx.gbl
| > | Xref: cpmsftngxa06.phx.gbl
| microsoft.public.dotnet.languages.csharp:191157
| > | NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
| > |
| > |
| > | HI Timothy,
| > |
| > | On my machine, when I consume the dll, the printf works well and no
| error
| > | generates.
| > | Btw: In your second printf, you should use %d to show your data, if
you
| > use
| > | %c, it will display it as Ascii.
| > |
| > | Best regards,
| > | Jeffrey Tan
| > | Microsoft Online Partner Support
| > | Get Secure! - www.microsoft.com/security
| > | This posting is provided "as is" with no warranties and confers no
| rights.
| > |
| > | --------------------
| > | | X-Tomcat-ID: 235590570
| > | | References: <eN**************@tk2msftngp13.phx.gbl>
| > | | MIME-Version: 1.0
| > | | Content-Type: text/plain
| > | | Content-Transfer-Encoding: 7bit
| > | | From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| > | | Organization: Microsoft
| > | | Date: Tue, 14 Oct 2003 09:37:27 GMT
| > | | Subject: RE: Need help with importing unmanaged code
| > | | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| > | | Message-ID: <Lq**************@cpmsftngxa06.phx.gbl>
| > | | Newsgroups: microsoft.public.dotnet.languages.csharp
| > | | Lines: 132
| > | | Path: cpmsftngxa06.phx.gbl
| > | | Xref: cpmsftngxa06.phx.gbl
| > microsoft.public.dotnet.languages.csharp:191149
| > | | NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
| > | |
| > | |
| > | | Hi Timothy,
| > | |
| > | | Normally, there are 2 ways of interop with unmanaged dll, safe way
and
| > | | unsafe way.
| > | | While the unsafe way is not recommanded, because its memory
operations
| > | are
| > | | all not safe.
| > | | Here is the safe way of consuming the unmanaged dll:
| > | |
| > | | [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| > | | static extern void ReturnCharPointer( byte []bytebuf , int
buffersize,
| >
| > | | IntPtr charbuf, int charbufsize);
| > | |
| > | | int a = 100;
| > | | int b = 75;
| > | | byte[] bytebuf = new byte[a];
| > | | IntPtr charbuf = Marshal.AllocHGlobal(b);
| > | |
| > | | for(int i =0; i <a; i++)
| > | | {
| > | | bytebuf[i]= Convert.ToByte(i);
| > | | }
| > | | ReturnCharPointer(bytebuf,a,charbuf,b);
| > | |
| > | | for(int k=0;k<b;k++)
| > | | {
| > | | Console.WriteLine(Marshal.ReadByte(charbuf,k));
| > | | }
| > | |
| > | | In the last for loop, I use Marshal.Read* function to retrieve data
| > from
| > | | unmanaged memory. You can also create a char array in managed memory
| > and
| > | | use Marshal.Copy method to copy the unmanaged memory to managed
| memory,
| > | | then it will be comfortable to use.
| > | |
| > | | If you still want to use unsafe way to interop the unmanaged dll,
you
| > | | should alloc the memory from unmanaged memory, but your code alloc
| from
| > | the
| > | | managed memory.
| > | | You can do like this:
| > | | [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| > | | unsafe static extern void ReturnCharPointer( byte *bytebuf , int
| > | | buffersize, char * charbuf, int charbufsize);
| > | |
| > | | int a = 100;
| > | | int b = 75;
| > | |
| > | | byte* bytebuf=(byte*)Marshal.AllocCoTaskMem(a);
| > | | char* charbuf=(char*)Marshal.AllocCoTaskMem(b);
| > | |
| > | | for(int i =0; i <a; i++)
| > | | {
| > | | bytebuf[i]= Convert.ToByte(i);
| > | | }
| > | |
| > | | ReturnCharPointer( bytebuf,a, charbuf,b);
| > | |
| > | | After ReturnCharPointer method, in the memory window, you can see
that
| > | the
| > | | charbuf is what you want, but if you want to show it out, you should
| > | | interop with some umanaged function such as printf, MessageBoxA to
| show
| > | it
| > | | out.
| > | |
| > | | Hope this helps,
| > | |
| > | | Best regards,
| > | | Jeffrey Tan
| > | | Microsoft Online Partner Support
| > | | Get Secure! - www.microsoft.com/security
| > | | This posting is provided "as is" with no warranties and confers no
| > rights.
| > | |
| > | | --------------------
| > | | | From: "Timothy Shih" <ts***@sensicast.com>
| > | | | Subject: Need help with importing unmanaged code
| > | | | Date: Mon, 13 Oct 2003 11:08:15 -0400
| > | | | Lines: 78
| > | | | X-Priority: 3
| > | | | X-MSMail-Priority: Normal
| > | | | X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| > | | | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| > | | | Message-ID: <eN**************@tk2msftngp13.phx.gbl>
| > | | | Newsgroups: microsoft.public.dotnet.languages.csharp
| > | | | NNTP-Posting-Host: dsl092-093-226.bos1.dsl.speakeasy.net
| 66.92.93.226
| > | | | Path:
cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!tk2msftn gp13.phx.gbl
| > | | | Xref: cpmsftngxa06.phx.gbl
| > | microsoft.public.dotnet.languages.csharp:190996
| > | | | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| > | | |
| > | | | Hi, I am trying to figure out how to use unmanaged code using
| > P/Invoke.
| > | I
| > | | | wrote a simple function which takes in 2 buffers (one a byte
buffer,
| > | one a
| > | | | char buffer) and copies the contents of the byte buffer into the
| > | character
| > | | | pointer. The code looks like the following:
| > | | |
| > | | | #include <stdio.h>
| > | | | #include <stdlib.h>
| > | | | #include "stdafx.h"
| > | | | BOOL APIENTRY DllMain( HANDLE hModule,
| > | | | DWORD ul_reason_for_call,
| > | | | LPVOID lpReserved
| > | | | )
| > | | | {
| > | | | return TRUE;
| > | | | }
| > | | |
| > | | | extern "C" __declspec(dllexport)
| > | | | void ReturnCharPointer(UINT8 *buffer, int buffersize, char
*charbuf,
| > int
| > | | | charbufsize) {
| > | | | int i =0;
| > | | | for(i=0; i < charbufsize; i++) {
| > | | | if(i>=buffersize)
| > | | | return;
| > | | | //printf("BYTE %d: %d\r\n",i,buffer[i]);
| > | | | charbuf[i] = buffer[i];
| > | | | //printf("CHAR %d: %c\r\n",i,charbuf[i]);
| > | | | }
| > | | | }
| > | | |
| > | | | Now I try to import that function with the following line in a C#
| > | project:
| > | | |
| > | | | [DllImport("DllShell")]
| > | | | unsafe static extern void ReturnCharPointer(byte *buffer, int
| > | buffersize,
| > | | | char *charbuf, int charbufsize);
| > | | |
| > | | | I use this in the following function:
| > | | |
| > | | | unsafe private void ParseBuffer()
| > | | | {
| > | | | int a = 100;
| > | | | int b = 75;
| > | | | byte[] bytebuf = new byte[a];
| > | | | char[] charbuf = new char[b];
| > | | | for(int i =0; i <a; i++)
| > | | | {
| > | | | bytebuf[i]= Convert.ToByte(i);
| > | | | }
| > | | | fixed(byte *bbuf=bytebuf)
| > | | | fixed(char *cbuf = charbuf)
| > | | | ReturnCharPointer(bbuf,a,cbuf,b);
| > | | | for(int i =0; i < b; i++)
| > | | | {
| > | | | Console.Write(charbuf[i] + ", ");
| > | | | }
| > | | |
| > | | | }
| > | | |
| > | | | My problem is the following: I can import and run the code just
| fine.
| > | | | However, when the function exits, the data in the character buffer
| is
| > | not
| > | | | what is expected! The byte buffer contains the numbers 0-99, the
| > | character
| > | | | buffer, whose size is 75 contains the following : [0] = 256, [1] =
| > 770,
| > | | [2]
| > | | | = 1284, [3] = 1798.... etc. The rest of the array is incremented
at
| > the
| > | | same
| > | | | rate until index 37 which contains the value "74". Since 74 should
| be
| > | the
| > | | | last entry in the buffer, i suspect that the data is somehow being
| > | | squashed
| > | | | on the way into or out of the unmanaged C dll. Also I was unable
to
| > use
| > | | | printf in the dll as it threw the following compiler error:
| > | | | "error C3861: 'printf': identifier not found, even with
| > | argument-dependent
| > | | | lookup"
| > | | |
| > | | | If anyone has any clue as to what is going on, it would be greatly
| > | | | appreciated!!
| > | | |
| > | | | Thanks,
| > | | | Tim
| > | | |
| > | | |
| > | | |
| > | | |
| > | | |
| > | |
| > | |
| > |
| > |
| >
|
|
|

Nov 15 '05 #7

P: n/a
Yes, it turned out that the #include for stdafx.h needed to be first before
any other includes, for some reason. Thanks for your help!

Tim
""Jeffrey Tan[MSFT]"" <v-*****@online.microsoft.com> wrote in message
news:7J**************@cpmsftngxa06.phx.gbl...

Hi Timothy,

Has your problem been resolved?
If it still does not work, please feel free to let me know.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: "Timothy Shih" <ts***@sensicast.com>
| References: <eN**************@tk2msftngp13.phx.gbl>
<Lq**************@cpmsftngxa06.phx.gbl>
<Da**************@cpmsftngxa06.phx.gbl>
<El**************@cpmsftngxa06.phx.gbl>
| Subject: Re: Need help with importing unmanaged code
| Date: Fri, 17 Oct 2003 14:34:14 -0400
| Lines: 314
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| Message-ID: <Od**************@TK2MSFTNGP09.phx.gbl>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: dsl092-093-226.bos1.dsl.speakeasy.net 66.92.93.226
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTN GP09.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:192165 | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Yep, that was the problem! Thanks a lot for your help. Also, I am still
| unable to compile with printf, sprintf or fprintf, even though I have
| #included stdio.h. Do you have any idea why I can't use these functions?
|
| Thanks again!
| Tim
|
|
| ""Jeffrey Tan[MSFT]"" <v-*****@online.microsoft.com> wrote in message
| news:El**************@cpmsftngxa06.phx.gbl...
| >
| > Hi Timothy,
| >
| > You can also alloc your memory from managed memory, but you should
marshal
| > it correctly.
| > Sample code like this:
| > [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| > static extern void
| > ReturnCharPointer([In,Out,MarshalAs(UnmanagedType.LPArray,
| > SizeParamIndex=1)] byte []bytebuf,int
| > buffersize,[In,Out,MarshalAs(UnmanagedType.LPArray, SizeParamIndex=3)]
| char
| > []charbuf,int charbufsize);
| >
| > int a = 100;
| > int b = 75;
| > byte[] bytebuf = new byte[a];
| > char[] charbuf = new char[b];
| > for(int i =0; i <a; i++)
| > {
| > bytebuf[i]= Convert.ToByte(i);
| > }
| >
| > ReturnCharPointer( bytebuf,a, charbuf,b);
| > for(int k=0; k< b;k++)
| > {
| > Console.Write(Convert.ToInt32(charbuf[k]) + ", ");
| > }
| >
| > It works well on my machine, if you still have any question, please feel | > free to let me know.
| >
| > Btw: I think the strange display of your code is because in C# a char is | > 2-bytes, while in C/C++ a char is 1-byte long. You¡¯ve got an
| ASCII/UNICODE
| > mismatch when you are passing in the char* from C#.
| >
| > Hope all these help
| >
| > Best regards,
| > Jeffrey Tan
| > Microsoft Online Partner Support
| > Get Secure! - www.microsoft.com/security
| > This posting is provided "as is" with no warranties and confers no
rights.
| >
| > --------------------
| > | X-Tomcat-ID: 243569578
| > | References: <eN**************@tk2msftngp13.phx.gbl>
| > <Lq**************@cpmsftngxa06.phx.gbl>
| > | MIME-Version: 1.0
| > | Content-Type: text/plain
| > | Content-Transfer-Encoding: 7bit
| > | From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| > | Organization: Microsoft
| > | Date: Tue, 14 Oct 2003 09:58:58 GMT
| > | Subject: RE: Need help with importing unmanaged code
| > | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| > | Message-ID: <Da**************@cpmsftngxa06.phx.gbl>
| > | Newsgroups: microsoft.public.dotnet.languages.csharp
| > | Lines: 169
| > | Path: cpmsftngxa06.phx.gbl
| > | Xref: cpmsftngxa06.phx.gbl
| microsoft.public.dotnet.languages.csharp:191157
| > | NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
| > |
| > |
| > | HI Timothy,
| > |
| > | On my machine, when I consume the dll, the printf works well and no
| error
| > | generates.
| > | Btw: In your second printf, you should use %d to show your data, if
you
| > use
| > | %c, it will display it as Ascii.
| > |
| > | Best regards,
| > | Jeffrey Tan
| > | Microsoft Online Partner Support
| > | Get Secure! - www.microsoft.com/security
| > | This posting is provided "as is" with no warranties and confers no
| rights.
| > |
| > | --------------------
| > | | X-Tomcat-ID: 235590570
| > | | References: <eN**************@tk2msftngp13.phx.gbl>
| > | | MIME-Version: 1.0
| > | | Content-Type: text/plain
| > | | Content-Transfer-Encoding: 7bit
| > | | From: v-*****@online.microsoft.com ("Jeffrey Tan[MSFT]")
| > | | Organization: Microsoft
| > | | Date: Tue, 14 Oct 2003 09:37:27 GMT
| > | | Subject: RE: Need help with importing unmanaged code
| > | | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| > | | Message-ID: <Lq**************@cpmsftngxa06.phx.gbl>
| > | | Newsgroups: microsoft.public.dotnet.languages.csharp
| > | | Lines: 132
| > | | Path: cpmsftngxa06.phx.gbl
| > | | Xref: cpmsftngxa06.phx.gbl
| > microsoft.public.dotnet.languages.csharp:191149
| > | | NNTP-Posting-Host: TOMCATIMPORT1 10.201.218.122
| > | |
| > | |
| > | | Hi Timothy,
| > | |
| > | | Normally, there are 2 ways of interop with unmanaged dll, safe way
and
| > | | unsafe way.
| > | | While the unsafe way is not recommanded, because its memory
operations
| > | are
| > | | all not safe.
| > | | Here is the safe way of consuming the unmanaged dll:
| > | |
| > | | [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| > | | static extern void ReturnCharPointer( byte []bytebuf , int
buffersize,
| >
| > | | IntPtr charbuf, int charbufsize);
| > | |
| > | | int a = 100;
| > | | int b = 75;
| > | | byte[] bytebuf = new byte[a];
| > | | IntPtr charbuf = Marshal.AllocHGlobal(b);
| > | |
| > | | for(int i =0; i <a; i++)
| > | | {
| > | | bytebuf[i]= Convert.ToByte(i);
| > | | }
| > | | ReturnCharPointer(bytebuf,a,charbuf,b);
| > | |
| > | | for(int k=0;k<b;k++)
| > | | {
| > | | Console.WriteLine(Marshal.ReadByte(charbuf,k));
| > | | }
| > | |
| > | | In the last for loop, I use Marshal.Read* function to retrieve data | > from
| > | | unmanaged memory. You can also create a char array in managed memory | > and
| > | | use Marshal.Copy method to copy the unmanaged memory to managed
| memory,
| > | | then it will be comfortable to use.
| > | |
| > | | If you still want to use unsafe way to interop the unmanaged dll,
you
| > | | should alloc the memory from unmanaged memory, but your code alloc
| from
| > | the
| > | | managed memory.
| > | | You can do like this:
| > | | [DllImport("dlltest.dll",CharSet=CharSet.Ansi)]
| > | | unsafe static extern void ReturnCharPointer( byte *bytebuf , int
| > | | buffersize, char * charbuf, int charbufsize);
| > | |
| > | | int a = 100;
| > | | int b = 75;
| > | |
| > | | byte* bytebuf=(byte*)Marshal.AllocCoTaskMem(a);
| > | | char* charbuf=(char*)Marshal.AllocCoTaskMem(b);
| > | |
| > | | for(int i =0; i <a; i++)
| > | | {
| > | | bytebuf[i]= Convert.ToByte(i);
| > | | }
| > | |
| > | | ReturnCharPointer( bytebuf,a, charbuf,b);
| > | |
| > | | After ReturnCharPointer method, in the memory window, you can see
that
| > | the
| > | | charbuf is what you want, but if you want to show it out, you should | > | | interop with some umanaged function such as printf, MessageBoxA to
| show
| > | it
| > | | out.
| > | |
| > | | Hope this helps,
| > | |
| > | | Best regards,
| > | | Jeffrey Tan
| > | | Microsoft Online Partner Support
| > | | Get Secure! - www.microsoft.com/security
| > | | This posting is provided "as is" with no warranties and confers no
| > rights.
| > | |
| > | | --------------------
| > | | | From: "Timothy Shih" <ts***@sensicast.com>
| > | | | Subject: Need help with importing unmanaged code
| > | | | Date: Mon, 13 Oct 2003 11:08:15 -0400
| > | | | Lines: 78
| > | | | X-Priority: 3
| > | | | X-MSMail-Priority: Normal
| > | | | X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
| > | | | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
| > | | | Message-ID: <eN**************@tk2msftngp13.phx.gbl>
| > | | | Newsgroups: microsoft.public.dotnet.languages.csharp
| > | | | NNTP-Posting-Host: dsl092-093-226.bos1.dsl.speakeasy.net
| 66.92.93.226
| > | | | Path:
cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!tk2msftn gp13.phx.gbl
| > | | | Xref: cpmsftngxa06.phx.gbl
| > | microsoft.public.dotnet.languages.csharp:190996
| > | | | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| > | | |
| > | | | Hi, I am trying to figure out how to use unmanaged code using
| > P/Invoke.
| > | I
| > | | | wrote a simple function which takes in 2 buffers (one a byte
buffer,
| > | one a
| > | | | char buffer) and copies the contents of the byte buffer into the
| > | character
| > | | | pointer. The code looks like the following:
| > | | |
| > | | | #include <stdio.h>
| > | | | #include <stdlib.h>
| > | | | #include "stdafx.h"
| > | | | BOOL APIENTRY DllMain( HANDLE hModule,
| > | | | DWORD ul_reason_for_call,
| > | | | LPVOID lpReserved
| > | | | )
| > | | | {
| > | | | return TRUE;
| > | | | }
| > | | |
| > | | | extern "C" __declspec(dllexport)
| > | | | void ReturnCharPointer(UINT8 *buffer, int buffersize, char
*charbuf,
| > int
| > | | | charbufsize) {
| > | | | int i =0;
| > | | | for(i=0; i < charbufsize; i++) {
| > | | | if(i>=buffersize)
| > | | | return;
| > | | | //printf("BYTE %d: %d\r\n",i,buffer[i]);
| > | | | charbuf[i] = buffer[i];
| > | | | //printf("CHAR %d: %c\r\n",i,charbuf[i]);
| > | | | }
| > | | | }
| > | | |
| > | | | Now I try to import that function with the following line in a C# | > | project:
| > | | |
| > | | | [DllImport("DllShell")]
| > | | | unsafe static extern void ReturnCharPointer(byte *buffer, int
| > | buffersize,
| > | | | char *charbuf, int charbufsize);
| > | | |
| > | | | I use this in the following function:
| > | | |
| > | | | unsafe private void ParseBuffer()
| > | | | {
| > | | | int a = 100;
| > | | | int b = 75;
| > | | | byte[] bytebuf = new byte[a];
| > | | | char[] charbuf = new char[b];
| > | | | for(int i =0; i <a; i++)
| > | | | {
| > | | | bytebuf[i]= Convert.ToByte(i);
| > | | | }
| > | | | fixed(byte *bbuf=bytebuf)
| > | | | fixed(char *cbuf = charbuf)
| > | | | ReturnCharPointer(bbuf,a,cbuf,b);
| > | | | for(int i =0; i < b; i++)
| > | | | {
| > | | | Console.Write(charbuf[i] + ", ");
| > | | | }
| > | | |
| > | | | }
| > | | |
| > | | | My problem is the following: I can import and run the code just
| fine.
| > | | | However, when the function exits, the data in the character buffer | is
| > | not
| > | | | what is expected! The byte buffer contains the numbers 0-99, the
| > | character
| > | | | buffer, whose size is 75 contains the following : [0] = 256, [1] = | > 770,
| > | | [2]
| > | | | = 1284, [3] = 1798.... etc. The rest of the array is incremented
at
| > the
| > | | same
| > | | | rate until index 37 which contains the value "74". Since 74 should | be
| > | the
| > | | | last entry in the buffer, i suspect that the data is somehow being | > | | squashed
| > | | | on the way into or out of the unmanaged C dll. Also I was unable
to
| > use
| > | | | printf in the dll as it threw the following compiler error:
| > | | | "error C3861: 'printf': identifier not found, even with
| > | argument-dependent
| > | | | lookup"
| > | | |
| > | | | If anyone has any clue as to what is going on, it would be greatly | > | | | appreciated!!
| > | | |
| > | | | Thanks,
| > | | | Tim
| > | | |
| > | | |
| > | | |
| > | | |
| > | | |
| > | |
| > | |
| > |
| > |
| >
|
|
|

Nov 15 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.