问题
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.
回答1:
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 ofstdcall
(thestdcall
in your declaration overrules thecdecl
) - 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.
来源:https://stackoverflow.com/questions/39471902/delphi-communication-with-c-dll-parameters