【发布时间】:2009-06-02 19:25:36
【问题描述】:
我正在尝试使用 p/invoke 从 c# 调用本机 .dll。我能够进行调用(没有崩溃,函数返回一个值),但返回代码指示“指针参数不指向可访问的内存”。为了解决这个问题,我采取了反复试验,但到目前为止我还没有取得任何进展。
这是我正在调用的本机函数的签名:
LONG extern WINAPI MyFunction ( LPSTR lpszLogicalName, //input
HANDLE hApp, //input
LPSTR lpszAppID, //input
DWORD dwTraceLevel, //input
DWORD dwTimeOut, //input
DWORD dwSrvcVersionsRequired, //input
LPWFSVERSION lpSrvcVersion, //WFSVERSION*, output
LPWFSVERSION lpSPIVersion, //WFSVERSION*, output
LPHSERVICE lphService //unsigned short*, output
);
这是在 C# 中导入的签名:
[DllImport("my.dll")]
public static extern int MyFunction( [MarshalAs(UnmanagedType.LPStr)]
string logicalName,
IntPtr hApp,
[MarshalAs(UnmanagedType.LPStr)]
string appID,
int traceLevel,
int timeout,
int srvcVersionsRequired,
[Out] WFSVersion srvcVersion,
[Out] WFSVersion spiVersion,
[Out] UInt16 hService
);
这是 WFSVERSION 的 C 定义:
typedef struct _wfsversion
{
WORD wVersion;
WORD wLowVersion;
WORD wHighVersion;
CHAR szDescription[257];
CHAR szSystemStatus[257];
} WFSVERSION, * LPWFSVERSION;
这是 WFSVersion 的 C# 定义:
[StructLayout(LayoutKind.Sequential)]
public class WFSVersion
{
public Int16 wVersion;
public Int16 wLowVersion;
public Int16 wHighVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 257)]
public char[] szDescription;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 257)]
public char[] szSystemStatus;
}
这是从 C# 对 MyFunction 的调用:
WFSVersion srvcVersionInfo = new WFSVersion();
WFSVersion spiVersionInfo = new WFSVersion();
UInt16 hService = 0;
IntPtr hApp = IntPtr.Zero;
string logicalServiceName = tbServiceName.Text;
int openResult = MyFunction(logicalServiceName, hApp, null, 0,
XFSConstants.WFS_INDEFINITE_WAIT,
0x00000004, srvcVersionInfo, spiVersionInfo,
hService);
正如我所说,此调用返回,但返回值是一个错误代码,指示“指针参数未指向可访问的内存”。我一定是对参数 1、3、7、8 或 9 做错了什么。但是,我已经成功调用了这个 .dll 中需要 WFSVERSION* 作为参数的其他函数,所以我不认为参数 7 或8是这里的问题。
如果您对这个问题的原因有任何想法,或者对我的代码提出任何建设性的批评,我将不胜感激。这是我第一次使用 P/Invoke,所以我不知道从哪里开始。有什么办法可以缩小问题的范围,还是我唯一的选择是试错?
【问题讨论】:
-
pinvoke.net 可能会有帮助
-
你在第三个参数中有一个空指针 - 这是正确的代码吗?
-
是的,空指针作为第三个参数是有效的。
标签: c# pointers interop pinvoke