• Advertisement
Sign in to follow this  

[.net] How to PInvoke function within a dll

This topic is 4331 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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..

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Thanks, but this site is only for known dll's..

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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 !

Share this post


Link to post
Share on other sites
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:

// declaration
public static extern int LmPrinterIoControl([In] byte[] inBuffer,Int32 inBufferSize,[In,Out] byte[] outBuffer,Int32 outBufferSize,ref Int32 bytesReturned);

// usage

byte[] 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.

Share this post


Link to post
Share on other sites
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 !!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement