473,385 Members | 1,357 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Need help with importing unmanaged code

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
7 3271

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

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

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

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

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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Edward S | last post by:
I budget for a Project in an Excel sheet as illustrated below. The months below are usually a 2 year period i.e. 24 months, though it could be over 24 months depending upon a Project. I then...
0
by: Stephen Horne | last post by:
I've only very recently started with .NET, and need to use some existing container libraries in new code. I'd like to minimise the amount of porting, but of course these containers are not designed...
1
by: Grant Frisken | last post by:
I have a function in a Managed C++ base class which looks something like: public __gc class Foo { virtual A* Bar(B* b, C*c); }; where A is an unmanaged class and B and C are managed classes....
7
by: Entwickler | last post by:
hello, i have the following problem. i want to write a code that enables the user to call functions from a unmanaged code .dll at running time . so i have to use the late binding . i tried the...
3
by: Kamen | last post by:
Hi, I am writing a software under .NET, what I need is a way to use my assemblies from within unamanaged c++ or VB6 projects. Is there a way that can help me import .NET assemblies within...
22
by: SQACSharp | last post by:
I'm trying to get the control name of an editbox in another window. The following code set the value "MyPassword" in the password EditBox but it fail to return the control name of the EditBox. ...
5
by: akash | last post by:
I'm having problems calling an unmanaged class from a managed wrapper. I suspect I'm missing something obvious, as I'm unfamiliar with C++ and classes are very simple. My unmanaged class is as...
4
by: Duncan Smith | last post by:
I have a VS2005 C++ MFC project which #imports a type library. The goal is to introduce some managed code eventually, but for starters I just need to set the /clr compiler option and build the...
1
by: raghaw | last post by:
Hi, I have a Project implemented in unmanaged C++ .There are various header files of it.I want to know how to use the header files of this project into my one of C++/CLI project???
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.