我有一个非托管的Delphi?库和我尝试从C#代码调用非托管函数,这需要分配内存来写入。我尝试在C#代码中分配内存,然后我面临访问冲突异常的问题。
1.从文档中我知道函数的调用约定是StdCall。我的目标平台是x64,我不知道它是否有用。
我用Google搜索并试图用Marshal.X功能解决问题,但他们没有帮助。现在,C#代码中的签名如下所示:
[DllImport(@"lib.dll", CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
internal static unsafe extern int Reg(
[MarshalAs(UnmanagedType.LPStr)]string host,
[MarshalAs(UnmanagedType.LPStr)]string port,
char arm,
[MarshalAs(UnmanagedType.LPStr)]string username,
[MarshalAs(UnmanagedType.LPStr)]string password,
void* answer,
[MarshalAs(UnmanagedType.I4)] int abufsize);
然后我用Marshal分配调用它并获得访问冲突。
unsafe
{
var answer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(char)) *
BUFSIZE).ToPointer();
rcode = Wrapper.Reg(_config.Host, _config.Port, _arm,
_user.Username, _user.Password, answer, BUFSIZE);
}
原始签名是
function reg(host: Pchar;
port: Pchar;
arm: char;
name,password: Pchar;
var answer: Pchar; abufsize: integer):integer;
现在我不知道如何处理访问冲突,并且不知道究竟是什么导致了这个问题。
UPD:可以调用相同的函数并使用不同的参数正确执行并返回错误代码,但是当它尝试写入缓冲区时,它会崩溃,因此问题与存储器中。
已解决:最后,我在C#签名中使用 ref 关键字解决了问题。令人惊讶的。
[DllImport(@"lib.dll", CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
internal static unsafe extern int Reg(
[MarshalAs(UnmanagedType.LPStr)]string host,
[MarshalAs(UnmanagedType.LPStr)]string port,
char arm,
[MarshalAs(UnmanagedType.LPStr)]string username,
[MarshalAs(UnmanagedType.LPStr)]string password,
ref byte* answer,
[MarshalAs(UnmanagedType.I4)] int abufsize);