Need help with importing unmanaged code

T

Timothy Shih

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);
charbuf = buffer;
//printf("CHAR %d: %c\r\n",i,charbuf);
}
}

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;
for(int i =0; i <a; i++)
{
bytebuf= 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 + ", ");
}

}

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
 
J

Jeffrey Tan[MSFT]

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= 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= 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" <[email protected]>
| 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: <[email protected]>
| 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!tk2msftngp13.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);
| charbuf = buffer;
| //printf("CHAR %d: %c\r\n",i,charbuf);
| }
| }
|
| 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;
| for(int i =0; i <a; i++)
| {
| bytebuf= 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 + ", ");
| }
|
| }
|
| 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
|
|
|
|
|
 
J

Jeffrey Tan[MSFT]

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: <[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain
| Content-Transfer-Encoding: 7bit
| From: (e-mail address removed) ("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: <[email protected]>
| 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= 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= 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" <[email protected]>
| | 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: <[email protected]>
| | 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!tk2msftngp13.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);
| | charbuf = buffer;
| | //printf("CHAR %d: %c\r\n",i,charbuf);
| | }
| | }
| |
| | 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;
| | for(int i =0; i <a; i++)
| | {
| | bytebuf= 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 + ", ");
| | }
| |
| | }
| |
| | 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
| |
| |
| |
| |
| |
|
|
 
J

Jeffrey Tan[MSFT]

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;
for(int i =0; i <a; i++)
{
bytebuf= 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: <[email protected]>
<[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain
| Content-Transfer-Encoding: 7bit
| From: (e-mail address removed) ("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: <[email protected]>
| 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: <[email protected]>
| | MIME-Version: 1.0
| | Content-Type: text/plain
| | Content-Transfer-Encoding: 7bit
| | From: (e-mail address removed) ("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: <[email protected]>
| | 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= 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= 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" <[email protected]>
| | | 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: <[email protected]>
| | | 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!tk2msftngp13.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);
| | | charbuf = buffer;
| | | //printf("CHAR %d: %c\r\n",i,charbuf);
| | | }
| | | }
| | |
| | | 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;
| | | for(int i =0; i <a; i++)
| | | {
| | | bytebuf= 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 + ", ");
| | | }
| | |
| | | }
| | |
| | | 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
| | |
| | |
| | |
| | |
| | |
| |
| |
|
|
 
T

Timothy Shih

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]" said:
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;
for(int i =0; i <a; i++)
{
bytebuf= 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: <[email protected]>
<[email protected]>
| MIME-Version: 1.0
| Content-Type: text/plain
| Content-Transfer-Encoding: 7bit
| From: (e-mail address removed) ("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: <[email protected]>
| 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: <[email protected]>
| | MIME-Version: 1.0
| | Content-Type: text/plain
| | Content-Transfer-Encoding: 7bit
| | From: (e-mail address removed) ("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: <[email protected]>
| | 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= 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= 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" <[email protected]>
| | | 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: <[email protected]>
| | | 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!tk2msftngp13.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);
| | | charbuf = buffer;
| | | //printf("CHAR %d: %c\r\n",i,charbuf);
| | | }
| | | }
| | |
| | | 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;
| | | for(int i =0; i <a; i++)
| | | {
| | | bytebuf= 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 + ", ");
| | | }
| | |
| | | }
| | |
| | | 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
| | |
| | |
| | |
| | |
| | |
| |
| |
|
|
 
J

Jeffrey Tan[MSFT]

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" <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
| 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: <[email protected]>
| 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!TK2MSFTNGP09.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
|
|
| | >
| > 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;
| > for(int i =0; i <a; i++)
| > {
| > bytebuf= 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: <[email protected]>
| > <[email protected]>
| > | MIME-Version: 1.0
| > | Content-Type: text/plain
| > | Content-Transfer-Encoding: 7bit
| > | From: (e-mail address removed) ("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: <[email protected]>
| > | 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: <[email protected]>
| > | | MIME-Version: 1.0
| > | | Content-Type: text/plain
| > | | Content-Transfer-Encoding: 7bit
| > | | From: (e-mail address removed) ("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: <[email protected]>
| > | | 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= 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= 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" <[email protected]>
| > | | | 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: <[email protected]>
| > | | | 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!tk2msftngp13.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);
| > | | | charbuf = buffer;
| > | | | //printf("CHAR %d: %c\r\n",i,charbuf);
| > | | | }
| > | | | }
| > | | |
| > | | | 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;
| > | | | for(int i =0; i <a; i++)
| > | | | {
| > | | | bytebuf= 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 + ", ");
| > | | | }
| > | | |
| > | | | }
| > | | |
| > | | | 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
| > | | |
| > | | |
| > | | |
| > | | |
| > | | |
| > | |
| > | |
| > |
| > |
| >
|
|
|
 
J

Jeffrey Tan[MSFT]

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" <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
| 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: <[email protected]>
| 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!TK2MSFTNGP09.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
|
|
| | >
| > 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;
| > for(int i =0; i <a; i++)
| > {
| > bytebuf= 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: <[email protected]>
| > <[email protected]>
| > | MIME-Version: 1.0
| > | Content-Type: text/plain
| > | Content-Transfer-Encoding: 7bit
| > | From: (e-mail address removed) ("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: <[email protected]>
| > | 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: <[email protected]>
| > | | MIME-Version: 1.0
| > | | Content-Type: text/plain
| > | | Content-Transfer-Encoding: 7bit
| > | | From: (e-mail address removed) ("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: <[email protected]>
| > | | 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= 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= 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" <[email protected]>
| > | | | 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: <[email protected]>
| > | | | 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!tk2msftngp13.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);
| > | | | charbuf = buffer;
| > | | | //printf("CHAR %d: %c\r\n",i,charbuf);
| > | | | }
| > | | | }
| > | | |
| > | | | 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;
| > | | | for(int i =0; i <a; i++)
| > | | | {
| > | | | bytebuf= 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 + ", ");
| > | | | }
| > | | |
| > | | | }
| > | | |
| > | | | 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
| > | | |
| > | | |
| > | | |
| > | | |
| > | | |
| > | |
| > | |
| > |
| > |
| >
|
|
|
 
T

Timothy Shih

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]" said:
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" <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
| 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: <[email protected]>
| 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!TK2MSFTNGP09.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
|
|
| | >
| > 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;
| > for(int i =0; i <a; i++)
| > {
| > bytebuf= 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: <[email protected]>
| > <[email protected]>
| > | MIME-Version: 1.0
| > | Content-Type: text/plain
| > | Content-Transfer-Encoding: 7bit
| > | From: (e-mail address removed) ("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: <[email protected]>
| > | 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: <[email protected]>
| > | | MIME-Version: 1.0
| > | | Content-Type: text/plain
| > | | Content-Transfer-Encoding: 7bit
| > | | From: (e-mail address removed) ("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: <[email protected]>
| > | | 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= 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= 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" <[email protected]>
| > | | | 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: <[email protected]>
| > | | | 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!tk2msftngp13.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);
| > | | | charbuf = buffer;
| > | | | //printf("CHAR %d: %c\r\n",i,charbuf);
| > | | | }
| > | | | }
| > | | |
| > | | | 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;
| > | | | for(int i =0; i <a; i++)
| > | | | {
| > | | | bytebuf= 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 + ", ");
| > | | | }
| > | | |
| > | | | }
| > | | |
| > | | | 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
| > | | |
| > | | |
| > | | |
| > | | |
| > | | |
| > | |
| > | |
| > |
| > |
| >
|
|
|
 

Ask a Question

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

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

Ask a Question

Top