使用 P/Invoke 会导致系统访问违规异常
Using P/Invoke causes system AccessViolationException
我在使用 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# 链接,但我看不到问题出在哪里。任何帮助将不胜感激。
默认情况下,P/Invoke 将 C# string
封送到 C 字符串中。你的C函数的参数应该是一个const char*
,而不是一个std::string
。
通常,应避免导出具有依赖于非 POD 类型的签名的函数,例如 std::string
。使用者(在本例中为 C#)不知道 DLL 使用的std::string
的内存布局,因此它甚至无法创建一个用于调用函数的内存布局。
相关文章:
- Windows 后台服务(系统配置文件)无法使用 C++ 访问 win 10 上的用户 appData 文件夹?
- 如何访问基类向量中的子类变量?(对于实体组件系统)
- 16 位系统中的程序如何访问大于 65535 的整数,但不能访问地址
- C++ 17 文件系统copy_file访问被拒绝
- 访问另一个类(系统)的非静态字段,就好像它是我自己的字段一样 - 优雅地
- 并发内存访问减慢系统速度
- Boost文件系统存在访问违规
- 用户土地访问内核土地驱动程序系统通知
- 将WM_CHANGEUISTATE发送到窗口应用程序后,当用鼠标访问菜单时,助记符不会显示在系统菜单上
- 系统访问出界异常,尝试从flatbuffer的二进制文件访问"LengthofTable"
- 简单Boost文件系统访问冲突
- 我可以直接访问 Windows 内核系统调用吗?
- 如何访问系统目录C 中的文件
- 从服务应用程序访问访客帐户系统注册表
- 系统会冻结如果我使用运行的守护程序重新启动或关闭,该守护程序可以使用Fanotify控制对文件的访问
- Qt::如何识别/检测系统是否被Linux中的其他系统远程访问
- 动态链接 ~ 限制 DLL 的系统访问
- 用于访问系统资源信息的多平台库
- 如何通过Windows API访问系统规格?
- 时钟()在<ctime>访问系统时钟时如何工作?