我在使用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]);
}
为什么我看不到正确的结果?我在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];
}
}
}
可能结构是实际问题吗?
这是我使用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);
}
感谢您的帮助。
答案 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);