我有一个用 Delphi 编写的非托管 DLL 文件,其中包含一个具有以下定义的函数:
function F(tgran: integer; inputs: PDouble; goutp, outputs, toutp: PDouble): integer; stdcall; external 'mydll.dll';
我用 C# 编写了一个适配器,它应该可以帮助我使用它。
[UnmanagedFunctionPointer(APIAdapter.Convention)]
public delegate int FDelegate(int tgran, IntPtr inputs, IntPtr goutp, IntPtr outputs, IntPtr toutp);
public class APIAdapter : IDisposable
{
public const string DllName = "mydll.dll";
public const CallingConvention Convention = CallingConvention.StdCall;
public FDelegate F;
[DllImport("kernel32")]
private static extern IntPtr LoadLibrary(string lpLibFileName);
[DllImport("kernel32")]
private static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll")]
private static extern IntPtr GetProcAddress(IntPtr hModule, String procname);
private IntPtr _dllHandle;
public APIAdapter()
{
_dllHandle = LoadLibrary(DllName);
F = (FDelegate)GetFunction<CalcCavSpDelegate>("F");
}
private Delegate GetFunction<T>(string procName)
{
IntPtr procAddress = GetProcAddress(_dllHandle, procName);
return Marshal.GetDelegateForFunctionPointer(procAddress, typeof(T));
}
~APIAdapter()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing)
{
}
while (FreeLibrary(_dllHandle))
{
}
}
}
用法非常简单:
using(var api = new APIAdapter())
{
// Call API functions
}
问题是在 DLL 文件中发生的 AccessViolationException。
我试图将 PDouble 变量作为double[], double* (unsafe code), IntPtr
. 无论我选择哪种方法,这都是同一个故事。我试图大幅增加传入数组的大小以排除数组索引错误 - 再次出现 AccessViolation 异常。
将 PDouble 传递到非托管 Delphi DLL 文件的正确方法是什么?