我正在使用delphi开发一个应用,其中调用了我在vc中编译的dll,该dll只有一个方法,定义如下:
extern "C" _declspec(dllexport) void MyFunc(char** ppFilePath)
{
CString str = ppFilePath[0];
AfxMessagebox(str);
.....//其他操作
}
参数传递的是一个字符串数组,我在delphi中使用该函数的声明如下:
procedure MyFunc(list: array of PChar); external 'mydll.dll' name 'MyFunc';调用代码如下:
procedure TForm1.Button1Click(Sender: TObject);
var
  filename : array[1..2] of PChar;
  str1,str2 : string;
begin
str1 := 'E:\001.jpg';
str2 := 'E:\002.jpg';
filename[1] := @str1[1];
filename[2] := @str2[1];
MyFunc(filename);
end;在调用过程中,发现虽然dll调用成功,但是delphi传递过去的字符串数组好像是无效的,能够显示对话框,但是信息是乱码,dll函数中对字符串数组的其他操作也就无法进行。
请各位高手指点一二,该dll定义以及参数传递是否有问题,谢谢。

解决方案 »

  1.   

    用WINAPI指定默认的参数传递方式和默认的堆栈规则
    extern "C" _declspec(dllexport) void WINAPI MyFunc(char** ppFilePath)
      

  2.   

    procedure MyFunc(list: array of PChar); cdecl;external 'mydll.dll' name 'MyFunc';
      

  3.   

    问题出在这里:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      filename : array[1..2] of PChar;
      str1,str2 : string;
    begin
    str1 := 'E:\001.jpg';    //这个字符串的存储在哪?
    str2 := 'E:\002.jpg';    //这个字符串的存储在哪?
    filename[1] := @str1[1]; //建议改为PChar(str1);
    filename[2] := @str2[1]; //建议改为PChar(str2);
    MyFunc(filename);
    end;建议:将字符串的定义放在函数外边:
    str1 : String = 'E:\001.jpg'; //这个字符串的存储在哪?
    str2 : String = 'E:\002.jpg'; //这个字符串的存储在哪?procedure TForm1.Button1Click(Sender: TObject);
    Var
      ……………………
      

  4.   

    to hkbarton:如果按照你的方法定义导出函数,是不是在delphi声明使用的时候也要做一定的改动呢?谢谢to hiflower:你的方法好像可行,能够正常显示那个文件名字符串了,但是我对字符串其他的操作还是有点问题,出现了地址访问冲突的异常,怪事,我在一个vc测试程序下测试这个dll就完全没有问题,用到delphi就有异常,郁闷。恳请多多指点to Seahilly:试试了你的方法,好像问题不是出在你说的地方,但你的建议应该是对我有用的,我得得改改,呵呵,多谢。
      

  5.   

    一下应该没问题,本人测试过:
    void _stdcall MyFunc(char** ppFilePath)
    {
    CString str = ppFilePath[0];
    AfxMessagebox(str);
    .....//其他操作
    }
      

  6.   

    void _stdcall MyFunc(char** ppFilePath)
    {
    CString str = ppFilePath[0];
    AfxMessagebox(str);
    .....//其他操作
    }delphi
    procedure MyFunc(list: array of PChar); far;stdcall;external 'mydll.dll' name 'MyFunc';
      

  7.   

    我仔细看了你的程序,觉得问题有两个:
    1、Delphi的字符串实现与VC的字符数组不同,Delphi的字符串实际上也是类。好的做法应该用Delphi的字符数组与VC的字符数组对应;
    2、我有特别注意了你VC程序中的类型定义 char**, 双星号的类型定义让人不好理解,
    建议再定义类型:修改建议一:
    VC中定义类型:
      typedef pchararray char*[100]; VC的函数定义改为:extern "C" _declspec(dllexport) void MyFunc(pchararray* ppFilePath)
    {
    CString str = ppFilePath[0];
    AfxMessagebox(str);
    .....//其他操作
    }在Delphi中也定义对应类型:Type PCharArray = Array[0..99] of PChar;
         PPCharArray = ^PCharArray;同时定义100个字符串数组:Var  CharArray[0..99] of Array[0..255] of Char;Delphi的函数定义:procedure MyFunc(list: PPCharArray); external 'mydll.dll' name 'MyFunc';Delphi函数调用要求:
    先将字符串赋给字符数组各个元素,在调函数。
    修改建议二:
    VC中定义类型:
      typedef pchararray char[100]; VC的函数定义改为(pchararray&):extern "C" _declspec(dllexport) void MyFunc(pchararray& ppFilePath)在Delphi中也定义对应类型:Type PCharArray = Array[0..99] of PChar;同时定义100个字符串数组:Var  CharArray[0..99] of Array[0..255] of Char;Delphi的函数定义(Var list):procedure MyFunc(Var list: PCharArray); external 'mydll.dll' name 'MyFunc';Delphi函数调用要求:
    先将字符串赋给字符数组各个元素,在调函数。
      

  8.   

    delphi里也要使用同样的规则
    procedure MyFunc(list: array of PChar); stdcall;external 'mydll.dll' name 'MyFunc';