[.net] How to PInvoke function within a dll

Started by
16 comments, last by Main 17 years, 10 months ago
Hello Everyone, I need to PInvoke function within a dll, the function signature is (for example): BOOL Foo( PVOID inA, DWORD inB, PVOID outC, DWORD outD, PDWORD outE ); I tried this (C#), with no success : [DllImport("aa.dll")] static extern bool Foo( IntPtr inA, UIntPtr inB, [Out] byte[] outC, UIntPtr outD, IntPtr outE ); Where did I go wrong ? Thanks ! [Edited by - LessBread on June 7, 2006 3:06:51 PM]
Advertisement
What do you mean 'no success'? It looks plausible, but I have no experience of PInvoke really so I wouldn't know if it was wrong.
I'm getting access violation while trying to execute (P-Invoke) this function.
It may be the way I set up values to the parameters,
But first I would like to know if I wrote the "static extern ..." signature currectly..
I haven't used PInvoke using C# yet (only VB.NET) so I can't tell you if the signature is right. But you might want to check out PInvoke.NET. It's a wiki dedicated to PInvoke. I'm sure you'll find what you need there
Thanks, but this site is only for known dll's..
Try this:
static extern Int32 Foo(IntPtr inA,Int32 inB,out IntPtr outC,Int32 outD,out Int32 outE);


A BOOL is really an integer, not a bool (although it might still work with a bool instead of Int32). If you know the actual types of inA and outC, you should be able to define sequential layout structures for those and pass them directly, rather than using IntPtr. Note that "outD" implies an output parameter, but it's signature isn't a pointer, so it can't be a pointer.

Without the "real" signature (what do the parameters represent and how are they used) it's hard to provide a useful declaration. For example, if outD specifies how many DWORD values outE can hold, then you have a completely different ballgame than if outE is just a pointer to a single DWORD...
Hi Dave,

1.What do you mean by "Real signature" ?
isn't it the real signature ?

BOOL Foo(
PVOID inA,
DWORD inB,
PVOID outC,
DWORD outD,
PDWORD outE
);

BTW: I'm trying to invoke the function LmPrinterIoControl
fro here :
http://www.swecoin.se/CustomFiles/TTP%20Language%20Monitor%20Implementation.pdf


2. What's the difference between "out" and "ref" ?

Thanks again !
By "real signature" I meant "what do the parameters represent." With the document you provided, I now have what I need.

You'll need to do something like this:
// declarationpublic static extern int LmPrinterIoControl([In] byte[] inBuffer,Int32 inBufferSize,[In,Out] byte[] outBuffer,Int32 outBufferSize,ref Int32 bytesReturned);// usagebyte[] inBuffer = new byte[inBufferSize];// don't know where data in inBuffer comes from, assume it's filled at this point.byte[] outBuffer = new byte[outBufferSize];LmPrinterIoControl(inBuffer,inBufferSize,outBuffer,outBufferSize,ref bytesReturned);


I don't have any way of verifying this, but it looks ok.

edit:
To answer question #2, "out" says I'm not going to initialize this variable, so don't read it, just set it. "ref" says the variable can be both read and written.

Note that this is different from In,Out in brackets, which has to do with how the PInvoke marshals the variables between the caller and the called.
Thanks Dave, I will check it out !

btw: This function needs to send block of data to the printer,
and get a block of data (the answer).

For example, the block that been sent may ask for the printer status,
and the received block may contain and answer (out of paper, hot printer, etc.)

I read the pdf file, but I couldn't figure out the protocol,
which bytes array I need to send, in order get the answer ?

can you understand it from the document ?

Thanks !!
It looks to me like you need to set the inBuffer to the sequence of bytes shown in the TTPKEY structure. For example, to get the "General Status", you would set inBuffer to the sequence of bytes corresponding to

"\x1b\x05\x01", 3, 2, REG_BINARY, TEXT("Status General")


I don't know how the TTPKEY structure is defined, so I have no idea how long each field is. If you've got a header file for the API, you should be able to figure that out. You could write a C program that outputs the sequence of bytes for each command. That way you could see exactly what bytes you need for a particular command.

The return buffer (outBuffer) will contain a series of bytes corresponding to the values shown in the table under "Remarks". Again, I don't know exactly how those will appear, so you might write a C program to check that out as well.

This topic is closed to new replies.

Advertisement