通过 DllImport 在 C# 中调用 C 方法 - 尝试读取或写入受保护的内存

本文关键字:读取 内存 受保护 DllImport 调用 方法 通过 | 更新日期: 2023-09-27 18:31:39

我有一个dll - Lib.dll(用С或C++写)。我需要调用一个函数:

extern “C” DWORD call_sb_kernel(
DWORD       func,
void        *in_arg,
void        *out_arg);

参数说明如下: DWORD 函数 - 是一个数字
void *in_arg - 指向

typedef struct tagInArg{
void        *Reserved;
void        *in_struct;     
} InArg;

void *out_arg 指向

typedef struct tagOutArg{
DWORD           ErrorCode;        
DWORD           Flags;            
void            *Reserved;
void            *out_struct;     
} OutArg;

从函数返回结果。

我在 C# 中调用此函数

    [DllImport(LibPath, CallingConvention = CallingConvention.StdCall)]
    private static extern long call_sb_kernel(uint func, [In, Out] InArg inArg, [In, Out]       OutArg outArg);

    [StructLayout(LayoutKind.Sequential, Size = 128)]
    public struct InArg
    {
        public IntPtr Reserved;
        public IntPtr in_struct;
    }
    [StructLayout(LayoutKind.Sequential, Size = 128)]
    public struct OutArg
    {
        public Int32 ErrorCode;
        public Int32 Flags;
        public IntPtr Reserved;
        public IntPtr out_struct;
    }
    public void Test()
    {
        var outArg = new OutArg();
        var res = call_sb_kernel_std(0, new InArg(), outArg);
    }

我尝试了很多选择。这是最后一个版本。但是我收到运行时错误 - "尝试读取或写入受保护的内存"。如何调用此函数?

通过 DllImport 在 C# 中调用 C 方法 - 尝试读取或写入受保护的内存

call_sb_kernel需要两个指针,而不是结构。将您的定义更改为 ref InArg inArg, out OutArg outArg 并像call_sb_kernel_std(0, ref inArg, out outArg);一样使用它。