使用 P/Invoke 会导致系统 AccessViolationException [重复]
Posted
技术标签:
【中文标题】使用 P/Invoke 会导致系统 AccessViolationException [重复]【英文标题】:Using P/Invoke causes system AccessViolationException [duplicate] 【发布时间】:2016-03-09 21:25:31 【问题描述】:我在使用 P/Invoke 从 C# 代码中使用 C++ 函数时遇到问题。我使用http://www.codeproject.com/Articles/403285/P-Invoke-Tutorial-Basics-Part 上的教程作为基本示例,一旦我开始使用它,我就将它改编为我自己的代码。
这会产生 System.AccessViolationException,并带有附加信息:'尝试读取或写入受保护的内存。这通常表明其他内存已损坏。'
我的C++头文件'NativeLib.h'如下:
#include <string>
#ifndef _NATIVELIB_H_
#define _NATIVELIB_H_
#ifndef MYAPI
#define MYAPI
#endif
#ifdef __cplusplus
extern "C"
#endif
MYAPI float modelScore(std::string word);
#ifdef __cplusplus
#endif
#endif // _NATIVELIB_H_
其中 MYAPI 是定义为“MYAPI=__declspec(dllexport)”的预处理器定义。 .cpp 文件“NativeLib.cpp”如下:
#include "NativeLib.h"
#include <stdio.h>
#include "lm/model.hh"
#include <iostream>
#include <string>
MYAPI float modelScore(std::string word)
using namespace lm::ngram;
Model model(---MODEL FILE LOCATION---);
State state(model.BeginSentenceState()), out_state;
const Vocabulary &vocab = model.GetVocabulary();
return model.Score(state, vocab.Index(word), out_state);
我正在使用以下代码从 C# 访问它:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace PInvokeTest
class Program
static void Main(string[] args)
modelScore("a");
Console.WriteLine("Press enter to close...");
Console.ReadLine();
[DllImport("NativeLib.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern float modelScore(string word);
代码正在构建且没有失败,所有适当的库都链接并包含在头文件路径中。 C++ 代码在 C++ 本身上运行良好,所以我的问题在于将代码与 C# 链接,但我看不出问题出在哪里。任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:默认情况下,P/Invoke 将您的 C# string
编组为 C 字符串。您的 C 函数的参数应该是 const char*
,而不是 std::string
。
通常,您应该避免导出具有依赖于非 POD 类型的签名的函数,例如 std::string
。使用者(在本例中为 C#)不知道您的 DLL 使用的 std::string
的内存布局,因此它甚至无法创建一个来调用您的函数。
【讨论】:
谢谢,已经解决了!以上是关于使用 P/Invoke 会导致系统 AccessViolationException [重复]的主要内容,如果未能解决你的问题,请参考以下文章
使用 P/Invoke 调用 dll 时,为啥 LoadLibrary 在某些机器上会失败?
p/invoke 和 EnumDisplaySettingsEx 的困难
我应该如何使用 P/Invoke 将字符串数组传递给 C 库?