gpt4 book ai didi

c# p/invoke 编码指针困难

转载 作者:行者123 更新时间:2023-11-30 12:18:58 27 4
gpt4 key购买 nike

我正在尝试使用 p/invoke 从 c# 调用 native .dll。我能够进行调用(没有崩溃,函数返回一个值),但返回代码指示“指针参数不指向可访问的内存。”为了解决这个问题,我采取了反复试验,但到目前为止我还没有取得任何进展。

这是我正在调用的 native 函数的签名:

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,所以我不确定从哪里开始。有什么方法可以缩小问题的范围,或者试错是我唯一的选择吗?

最佳答案

这里有两个明显的错误。在您的结构定义中,您应该为 szDescription 和 szSystemStatus 使用 byte[] 而不是 char[]。

此外,您的 pInvoke 调用中的最后一个参数不是指针。当您调用 MyFunction 时,hService 为零,因此就函数而言是一个无效指针。 [Out] 是一个编码指令,告诉运行时何时何地复制数据,而不是指示参数是指针。您需要将 [Out] 更改为 out 或 ref 这告诉运行时 hService 是一个指针:

[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);

关于c# p/invoke 编码指针困难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/941440/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com