情況是這樣的,第三方提供一個dll以及一個C++的介面檔案,我需要通過該介面來開發程式,我這邊想直接把C++的介面檔案翻譯成delphi版的,然后用delphi開發。
現在的問題是第三方提供的C++介面檔案中類的成員函式沒有明確宣告為__cdecl和__stdcall,我在網上查到的是如果不指定,類的成員函式默認是__thiscall,this指標通過ECX暫存器傳引數,而__thiscall是只對C++有效,delphi是沒有類似的關鍵字的,所以導致呼叫到函式后this指標的值是不對的。自己寫了一個小例子來模仿該情況,跪求高手指教啊。
C++代碼
//1.h
class A{
public:
virtual void hsshowmessage()=0; //該結構沒有明確申明為__stdcall,默認應該是__thiscall
};
extern "C" __declspec(dllexport) A* CreateA(int a1,int b1);
//1.cpp
#include "1.h"
#include <windows.h>
#include <stdio.h>
class B:public A{
private:
public:
virtual void hsshowmessage(){ //希望在delphi中呼叫到該函式,由于delphi中該函式默認是stdcall,所以呼叫傳遞過來的this指標值不對,從列印資訊中可以看出來
char tmp[100];
//通過delphi呼叫到這里this指標的值與delphi中創建的物件的值不同。
sprintf(tmp,"c.dll->hsshowmessage:b=%d,i=%d,j=%d",int(this),i,j);
MessageBox(NULL,TEXT(tmp),TEXT(""),MB_OK);
}
int i;
int j;
};
__declspec(dllexport) A* CreateA(int a1,int b1){
//A* A::CreateA(int a1,int b1){
B* b= new B;
b->i=a1;
b->j=b1;
char tmp[100];
sprintf(tmp,"c.dll->CreateA:b=%d,i=%d,j=%d",int(b),b->i,b->j);
MessageBox(NULL,TEXT(tmp),TEXT(""),MB_OK);
return b;
}
delphi代碼
type
TForm1 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
A = class
procedure hsshowmessage();virtual;abstract; //delphi默認是stdcall的
end;
const QTDLL = 'c.dll';
function CreateA(a,b:Integer):A; cdecl;
var
Form1: TForm1;
implementation
{$R *.dfm}
function CreateA; external QTDLL;
procedure TForm1.btn1Click(Sender: TObject);
var
ta:A;
begin
ta:=CreateA(1,2);
Application.MessageBox(PChar('project1.ext->btn1click:a='+IntToStr(Integer(ta))),'');
ta.hsshowmessage;
end;
uj5u.com熱心網友回復:
c++ 中__thiscall約定主要指定給虛函式的,通常第三方還會提供一個相應的com介面吧,問他們有沒有沒搞過這種勾當,你可以看看下面的做法
http://stackoverflow.com/questions/2667925/pass-a-delphi-class-to-a-c-function-method-that-expects-a-class-with-thiscal
uj5u.com熱心網友回復:
另外delphi的函式呼叫約定默認是register(fastcall),不是stdcalluj5u.com熱心網友回復:
預設的呼叫方法delphi肯定會支持的。轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/117380.html
標籤:語言基礎/算法/系統設計
