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

Posted

技术标签:

【中文标题】通过 DllImport 在 C# 中调用 C 方法 - 尝试读取或写入受保护的内存【英文标题】:Call C method in C# by DllImport - attempt to read or write protected memory 【发布时间】:2014-11-24 13:13:57 【问题描述】:

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

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

此参数说明: DWORD func - 是一个数字 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);
    

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

【问题讨论】:

这是我尝试过的选项之一(Size = 128)。 我有这个功能的描述。但我不知道如何正确调用。 设置Size 属性是不必要的,字段的自动大小与C 代码期望的大小相匹配。 【参考方案1】:

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

【讨论】:

call_sb_kernel_std(0, ref inArg, out outArg) - 成功了。谢谢。

以上是关于通过 DllImport 在 C# 中调用 C 方法 - 尝试读取或写入受保护的内存的主要内容,如果未能解决你的问题,请参考以下文章

C# - DLLImport 和函数默认值

有啥方法可以调试从 C# DllImport 调用的 c++ dll?

c#使用DllImport调用c++dll的函数

C#调用C/C++的dll,一个库中包括多个函数,每调用一个函数都要用DllImport加载吗?求大神

通过 DllImport 调用非托管函数时堆损坏

调用从 c# 返回 char* 的 c++ dll 函数。无法使用 DllImport()