c# - Pinvoke 中的一个问题

标签 c# .net interop pinvoke marshalling

我在 C++ 原生 dll 中有以下函数,我想在 C# 应用程序中使用它。

DWORD __cdecl Foo(
        LPCTSTR             Input,
        TCHAR**             Output,          
        DWORD               Options,        
        ErroneousWord**     List = NULL,
        LPDWORD             Count = 0
        );

使用 Pinvoke

[DllImport("dllName", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
        public static extern UInt32 Foo(string InputWord, out string Output, UInt32 Options, out object List,out UInt32 Count);

调用代码:

            string output;
            object dummyError = null;
            uint dummyCount = 0;
            uint x = 0;
            Foo(Text, out output, x | y,out  dummyError,out dummyCount);

我得到以下异常

Attempted to read or write protected memory. This is often an indication that other memory is corrupt

附言: ErroneousWord 是结构体,我不需要它的输出,所以我将它编码为对象

最佳答案

该错误很可能意味着您遇到了编码问题。

您没有向我们展示 ErroneousWord 类型是什么,但我假设它是您的 C++ 代码中定义的某种类。我的猜测是它没有被正确编码为 .NET object

考虑到它是一个指针(或指向指针的指针),尝试将该参数更改为 IntPtr type来代表一个指针,而不是。这无关紧要,因为您只是简单地为参数传递 NULL,使用静态 IntPtr.Zero field 很容易表示.

您可能还想以完全相同的方式编码 Output。如果将参数更改为 IntPtr 类型,您将收到一个指向 TCHAR* 的指针,然后您可以将其传递给其他您认为合适的非托管函数(例如,释放它)。

试试下面的代码:

[
DllImport("dllName",
CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl)
]
public static extern UInt32 Foo(
                                string InputWord,
                                out IntPtr Output,     // change to IntPtr
                                UInt32 Options,
                                out IntPtr List,       // change to IntPtr
                                out UInt32 Count);

IntPtr output;
IntPtr dummyError = IntPtr.Zero;
uint dummyCount = 0;
uint x = 0;
Foo(Text, out output, x | y, out dummyError, out dummyCount);

您可能还需要使用 Marshal.AllocHGlobal method从您的进程中分配 C++ 代码可访问的非托管内存。确保如果你这样做,你也调用相应的 Marshal.FreeHGlobal method释放内存。

关于c# - Pinvoke 中的一个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6018685/

相关文章:

c# - 调试失败的 HTTPS WebRequest

interop - 如何从 Blazor 调用 JS 异步方法

c++ - 为什么 ByRef 在传递给非托管代码时给出异常?

c# - 在 Docx 文件*周围*运行中的文本中插入注释

c# - 如何使用 C# 从文件中获取 EXIF 数据

c# - FluentValidation 何时不引发任何消息

.net - 将对象转换为字符串的最佳实践

c# - 当我要求 dotMemory 强制垃圾收集时究竟会发生什么

c# - 从配对列表中删除 'duplicates'

c# - F# OOP - 实现接口(interface) - 私有(private)和方法名称问题