Gunalp Alp Uysal
Gunalp Alp Uysal

Reputation: 47

how to use Pchar function to use c#

How can I use this function in C#?

function CheckCard (pPortID:LongInt;pReaderID:LongInt;pTimeout:LongInt): PChar;

This function included the dll.

I can try this way:

[DllImport("..\\RFID_107_485.dll", CharSet = CharSet.Auto, 
    CallingConvention = CallingConvention.ThisCall)]
public static extern char CheckCard(int pccPortID, int pccdReaderID, int pccTimeout);
                     char pccCheckCard = CheckCard(3, 129, 1000);
                     Console.WriteLine(pccCheckCard);

but i don't get a true answer...

please help me ? :)

Upvotes: 4

Views: 1233

Answers (1)

David Heffernan
David Heffernan

Reputation: 613592

There are many problems here. This is what I can see:

  1. The Delphi code as written uses the Delphi register calling convention. That is only accessible from Delphi code and cannot be called by a p/invoke method. However, it is possible that you have omitted the calling convention from the code and it is in fact stdcall.
  2. Your p/invoke uses CallingConvention.ThisCall which certainly does not match any Delphi function. That calling convention is not supported by Delphi.
  3. You mistranslate PChar, a pointer to null-terminated array of characters as char, a single UTF-16 character.
  4. The Delphi code looks suspicious. The function returns PChar. Well, who is responsible for deallocating the string that is returned. I would not be surprised if the Delphi code was returning a pointer to a string variable that is destroyed when the function returns, a very common error.
  5. You refer to the DLL using a relative path. That is very risky because you cannot easily control whether or not the DLL will be found. Place the DLL in the same directory as the executable, and specify just the DLL's file name.
  6. There is no error checking to be seen.

A variant that might work could look like this:

Delphi

function CheckCard(pPortID: LongInt; pReaderID: LongInt; pTimeout: LongInt): PChar; 
    stdcall;

C#

[DllImport("RFID_107_485.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr CheckCard(int pccPortID, int pccdReaderID, int pccTimeout);
....
IntPtr pccCheckCard = CheckCard(3, 129, 1000);
// check pccCheckCard for errors, presumably IntPtr.Zero indicates an error

// assuming ANSI text
string strCheckCard = Marshal.PtrToStringAnsi(pccCheckCard);
// or if the Delphi code returns UTF-16 text      
string strCheckCard = Marshal.PtrToStringUni(pccCheckCard);

This leaves unresolved how to deallocate the pointer returned. You'll have to consult your documentation for the function to find that out. The question contains insufficient information.

Upvotes: 2

Related Questions