如何从delphi编译的dll中调用c ++中的函数

时间:2012-10-25 18:50:53

标签: c++ qt dll

我在使用delphi中创建的dll库时遇到问题。我没有它的来源 - 只有DLL和接口。我想在我的c ++程序中导入它。我不需要使用QT进行加载(但它可能是最佳选择) - 标准的Windows API也适用。

首先, dll的界面:

Unit VPInterface;
interface

type
 TSignal     = array of double;
 ShortVector = array[0..11] of double;

function VP(s: TSignal): ShortVector; stdcall;
 stdcall external 'VoicePrint.dll' name 'VP';

implementation

End {VPInterface.pas}.

QT版本:

typedef double* (*VPFunct)(double[]);
vector<double> v_double;
// put some values in v_double
QLibrary lib("VoicePrint.dll");
VPFunct vpfunct = (VPFunct) lib.resolve("VP");
if (vpfunct) {
  double * res = vpfunct(&v_double[0]);
}
  1. 调用该函数并返回一些输出,但它是垃圾。如您所见,我传递了内部向量的数组(&amp; v_double [0])。我尝试在堆栈上使用双数组但功能尚未完成。有人可以解释一下原因吗?
  2. 为什么我看不到正确的结果?我在C#中有类似的代码,它可以工作:

    namespace WAT_DLL_TEST
    {
    public class VoicePrint
    {
        [DllImport("VoicePrint.dll", CharSet = CharSet.Ansi, EntryPoint = "VP", CallingConvention = CallingConvention.StdCall)]
        [return: MarshalAs(UnmanagedType.Struct)]
        public static extern ShortVector VP(double[] signal);
    
    
        [StructLayout(LayoutKind.Explicit, Size = 48)]
        public unsafe struct ShortVector
        {
            [FieldOffset(0)]
            public fixed double m_buffer[6];
        }
    
    }
    }
    
  3. 可能结构是实际问题吗?

    这是我使用windows api运行它的代码:

    HINSTANCE hinstDLL;
    VPFunct myFunct;
    BOOL fFreeDLL;
    
    hinstDLL = LoadLibrary(L"VoicePrint.dll");
    if (hinstDLL != NULL)
    {
        myFunct = (VPFunct) GetProcAddress(hinstDLL, "VP");
        if (myFunct != NULL) {
            double * dptr = myFunct(&v_double[0]);
            for(int i=0; i<11; i++)
                cout << dptr[i] << endl;
        }
        fFreeDLL = FreeLibrary(hinstDLL);
    }
    

    感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您应该在typedef中提及转换:

typedef double* (__stdcall *VPFunct)(double[]);

无效的呼叫转换会导致堆栈损坏。它可以解释每个不正确的行为。

您可以尝试使用以下代码模拟Delphi动态数组内存布局(提到here):

#pragma pack (push, 1)

template <uint32_t size>
struct DelphiArray
{
    uint32_t _refCounter;
    uint32_t _size;
    double array[size];
};
#pragma pack (pop)

然后使用DelphiArray这样调用函数

DelphiArray<N> arr;
arr._refCounter = 1;
arr._size = N;
//fill arr.array here
myFunc(arr.array);