Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi communication with C++ dll (parameters)

Hi I'm having quite some issues with integrating a DLL inside my Delphi 2007 application.

i suspect that I'm doing something wrong with the parameters of the calls. At this moment i have 2 issues, but i think they are related to eachother.

1) First call with the DLL: from the .h file:

extern "C" {

__declspec(dllexport) HRESULT Startup(char* version);

}

This call should initialize the DLL and give me the version back of the DLL. HRESULT should be 0, and the version pointer should contain the version.

My Delphi code:

function Startup(var version: Pchar): HRESULT; cdecl; stdcall; external 'myDLL.dll';

And the actual call:

var
  res : HRESULT;
  Name1 : PChar;
  test : AnsiString;
  buf2: array [0..20] of AnsiChar;
begin
  FillChar(buf2,20,0);
  Name1:= @buf2[0];
  res := RdmStartup(Name1);
//Here res = 0, but the Name1 stays empty, and the buf2 still contains 0.
end;

But as the result is 0 the call was a success.

Then my second issue: i need to call a function in the DLL that will open a COM port.

The .h:

extern "C" {
__declspec(dllexport) HRESULT Open(HWND hWnd, int Port, DWORD BaudRate, DWORD Interval); 
}

And my Delphi declare:

function Open(hWnd: HWND;Port : integer;BaudRate:LongInt;Interval:LongInt): HRESULT; cdecl; stdcall; external 'myDLL.dll';

and i call this by:

res:= Open(self.Handle,5,115200,500);

And here i'm getting a failure back from the DLL in the res variable. i also have the source of the DLL, and the failure that i'm getting is from the part where the DLL is checking if the parameters are valid, if they are valid it will continue, else return the error i'm currently getting.

The things it is checking:

if(hWnd == NULL)
{
    return false;
}
if(BaudRate != 2400 && BaudRate != 9600 && BaudRate != 38400 && BaudRate != 115200)
{
    return false;
} 
if(IntervalTimer < 300)
{
    return false;
}
std::string strPortName = lexical_cast<std::string>( format("COM%d") % Port);
std::string strPortName(lpPortName.c_str());
std::string::size_type loci = strPortName.find("COM");
if( loci == std::string::npos )
{
    return false;
}
return true;

And one of these above is returning false on my call, because if the result of this function is false, the DLL gives the error i'm currently getting in the results. Does anyone have an idea of what i am doing wrong?

i've tried numerous of combinations for the types in the end i sticked to the conversion i found at: http://www.drbob42.com/delphi/headconv.htm i've also tried different ways of reading the char pointer, but all of them failed.....

So at this stage i know i am succesfully communicating with the DLL as i'm getting different HRESULTs back for the 2 calls, but i suspect my parameters are not working like the should.

I'm using Delphi 2007 and the C++ DLL was build with VS2010.

like image 696
Nick Avatar asked Nov 09 '22 09:11

Nick


1 Answers

The declaration of Startup is pretty suspicious:

__declspec(dllexport) HRESULT Startup(char* version);

This translates into:

function Startup(version: PAnsiChar): HResult; stdcall; external 'myDLL.dll';

So there should be no var there.

I got from your comments that the cdecl calling convention works for some of your code. In that case remove stdcall, since it overrules the preceding cdecl.

The declaration of Open() seems to be pretty OK (I would use DWORD as type, not Longint, especially since DWORD is Longword these days -- but in Win32 they are the same size, so that won't make any big difference for you). And you seem to be passing the right parameters too.

You did not write what the HRESULT value is that you get back. But I assume that the port COM5 simply cannot be opened with these settings.

What can you do?

You should remove the var from Startup().

So you can try:

  • to use cdecl instead of stdcall (the stdcall in your declaration overrules the cdecl)
  • to open different COM ports with different parameters
  • to decode the HRESULT that is returned.

A better diagnosis is not possible, from a distance, without the same hardware and software, sorry.

You could read my article on conversion. This has also a few paragraphs that explain how to debug the code to find out the proper calling convention. It can probably help you with more of your problems converting headers, too.

like image 183
Rudy Velthuis Avatar answered Nov 14 '22 22:11

Rudy Velthuis