C#/ C ++传递结构获得访问冲突异常

安德里亚·福斯蒂(Andrea Fausti)

早上好,我正准备实现pos设备。本机api是C ++库,我必须在C#项目中使用。我已经导入了几乎所有必需的功能(可以正常工作),但是其中有一个我还是无法做到。

这是C ++库中的函数:

__declspec(dllexport) void setHost(char* id, Host* host, char* trx, char* flag);

这是在C ++库中声明的结构:

typedef struct {
   int hostConnectionType;
   char ipAddress[15 + 1];
   int tcpPort;
   int hostTransportProtocol;
   char gtId[5 + 1];
   char gprsAPN[64 + 1];
   char gprsUserName[15 + 1];
   char gprsPassword[8 + 1];
   int tlsCertificateId;
   char personalizationId[10 + 1];
   int gtIndex;
} Host;

这是C ++演示项目中的用法示例:

Host test_host;
test_host.hostConnectionType = 3;
test_host.hostTransportProtocol = 2;
test_host.gtIndex = 9;
strcpy(test_host.ipAddress, "199.188.177.166");
test_host.tcpPort = 54321;
strcpy(test_host.gtId, "12345");
test_host.tlsCertificateId = 21985;
strcpy(test_host.personalizationId, "001");
MobilePosAdapter_dll("00000123", &test_host, "0000000001", "1000");

我在C#项目中所做的是声明Host结构:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Host
{
    public int hostConnectionType;

    public int hostTransportProtocol;

    public int tcpPort;

    public int tlsCertificateId;

    public int gtIndex;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string ipAddress;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
    public string gtId;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 65)]
    public string gprsAPN;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
    public string gprsUserName;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]
    public string gprsPassword;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
    public string personalizationId;
}

然后,声明函数,属性和符号:

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private delegate void cdecl__setHost([MarshalAs(UnmanagedType.LPStr)] string id, Host Host, [MarshalAs(UnmanagedType.LPStr)] string trx, [MarshalAs(UnmanagedType.LPStr)] string flags);

private static cdecl__setHost _setHost = (cdecl__setHost)Marshal.GetDelegateForFunctionPointer(NativeMethods.GetProcAddress(DllPtr, "setHost"), typeof(cdecl__setHost));

最后测试一下:

Host host = new Host()
{
    gtId = 12345,
    gtIndex = 0,
    hostConnectionType = 3,
    hostTransportProtocol = 2,
    ipAddress = "199.188.177.166",
    personalizationId = "001",
    tcpPort = 54321,
    tlsCertificateId = 21985
};

_setHost("00000123", host, "0000000001", "1000");

我有一个System.AccessViolationException

我怎么了

这是整个API中唯一具有结构作为参数的函数。其他函数具有返回值的结构,它们都可以正常工作。

格查尔考特尔

只是一个快速的猜测

在非托管方面,参数类型为Host*,在C ++中,您正在传递&test_host

但是,在C#端,您有一个struct(默认情况下是按副本传递,所以按值传递),而您只是传递host给具有以下声明参数的函数:

private delegate
    void cdecl __setHost(
        [MarshalAs(UnmanagedType.LPStr)] string id,
        Host host,    // <--------- HERE
        [MarshalAs(UnmanagedType.LPStr)] string trx,
        [MarshalAs(UnmanagedType.LPStr)] string flags
    );

请注意,您尚未向该host参数添加任何MarshalAs ,因此我想它会按副本传递,并且会发生一些损坏,因为接收函数希望获得一个指针(几个字节)而不是整个结构(几倍) )。

我要尝试的第一件事是添加任何要作为指针传递的提示,例如:

private delegate
    void cdecl __setHost(
        [MarshalAs(UnmanagedType.LPStr)] string id,
        ref Host host,    // <--------- HERE
        [MarshalAs(UnmanagedType.LPStr)] string trx,
        [MarshalAs(UnmanagedType.LPStr)] string flags
    );

并称它为

_setHost("00000123", ref host, "0000000001", "1000");

另外,请务必仔细检查Ackdari在注释中所说的内容-如果字段顺序在C#提供的内容和预期的本机代码之间不同,则也可能导致相同的异常。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C ++结构访问冲突

来自分类Dev

C:链表的结构初始化导致访问冲突异常

来自分类Dev

带有C#异常错误的C DLL(访问冲突)

来自分类Dev

捕获c ++“访问冲突写入异常”?

来自分类Dev

winrt c ++ / cx并发访问冲突异常

来自分类Dev

C++ 异常抛出:访问冲突写入

来自分类Dev

C#参数传递异常

来自分类Dev

从C#访问托管C ++结构

来自分类Dev

C#反射结构异常上的SetValue

来自分类Dev

C malloc结构抛出内存冲突异常(准系统示例)

来自分类Dev

在C ++中访问传递的结构数组

来自分类Dev

在 C# 中传递结构定义

来自分类Dev

C#中的异常

来自分类Dev

异常处理C#

来自分类Dev

内部异常C#

来自分类Dev

C#异常OutOfMemory

来自分类Dev

C#代码异常

来自分类Dev

C# 忽略异常

来自分类Dev

If .. And If ... And If的C#结构

来自分类Dev

C#结构推荐

来自分类Dev

抛出C ++异常:读取访问冲突。这是nullptr

来自分类Dev

securitymanager.dll异常访问冲突(c0000005)

来自分类Dev

WindowsError异常访问冲突-在简单的python c ++ ctypes接口中

来自分类Dev

RegQueryValueExW 在 C 中返回访问冲突读取位置异常

来自分类Dev

C#字典访问

来自分类Dev

C#属性访问

来自分类Dev

将结构从非托管C ++传递到C#

来自分类Dev

使用IntPtr将结构数组从C#传递到C ++

来自分类Dev

从 C# 代码访问在 C 代码中分配的结构内存