从 C# 调用 C++ dll 并抛出 SEHException

Posted

技术标签:

【中文标题】从 C# 调用 C++ dll 并抛出 SEHException【英文标题】:calling a C++ dll from C# throwing a SEHException 【发布时间】:2018-07-19 14:55:35 【问题描述】:

我正在尝试从 C# 代码调用我在 C++ 中构建的 dll。 但是,我收到以下错误:

抛出异常:'System.Runtime.InteropServices.SEHException' in dlltest_client.exe 类型未处理的异常 'System.Runtime.InteropServices.SEHException' 发生在 dlltest_client.exe 外部组件抛出异常。

我正在使用 cpp 代码构建 C++ dll,然后导入头文件:

dlltest.cpp

#include "stdafx.h"
#include <iostream>
#include <string>
#include "dlltest.h"

using namespace std;

// DLL internal state variables:
static string full_;
static string piece_;

void jigsaw_init(const string full_input, const string piece_input)

    full_ = full_input;
    piece_ = piece_input;


void findPiece()

    cout << full_;
    cout << piece_;

在哪里dlltest.h

#pragma once

#ifdef DLLTEST_EXPORTS
#define DLLTEST_API __declspec(dllexport)
#else
#define DLLTEST_API __declspec(dllimport)
#endif

extern "C" DLLTEST_API void jigsaw_init(
    const std::string full_input, const std::string piece_input);

extern "C" DLLTEST_API void findPiece();

这成功构建了 dlltest.dll

我应该使用 dll 的 C# 代码是

dlltest_client.cs

using System;
using System.Runtime.InteropServices;

class Program

    [DllImport(@"path\dlltest.dll")]
    private static extern void jigsaw_init(string full_input, string piece_input);
    [DllImport(@"path\dlltest.dll")]
    private static extern void findPiece();

    static void Main(string[] args)
    
        string full = @"path\monster_1.png";
        string piece = @"path\piece01_01.png";
        jigsaw_init(full, piece);
        findPiece();
    

【问题讨论】:

【参考方案1】:

您不能将 C++ std::string 用于非托管互操作,这就是您的 DLL 引发异常的原因。

改为使用指向以 null 结尾的字符数组的指针在 C# 代码和非托管 C++ 代码之间传递字符串。

另一个错误是 C++ 代码使用 cdecl 调用约定,但 C# 代码假定为 stdcall。你需要让界面的两侧匹配,改变一个来匹配另一个。

【讨论】:

谢谢,我越来越近了。但是,在实施了您的建议后,我只设法通过了第一个字符。 C++ 端:extern "C" DLLTEST_API void jigsaw_init(char* piece_input) 和 C# 端 [DllImport(@"path\dlltest.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] static extern void jigsaw_init(string str); CharSet.Unicode 传递 UTF-16 编码的文本。这将匹配 C++ 端的const wchar_t*。或者,您可以将 C++ 代码保留为 char*(注意它确实应该是 const char* 并恢复为 CharSet.Ansi

以上是关于从 C# 调用 C++ dll 并抛出 SEHException的主要内容,如果未能解决你的问题,请参考以下文章

从 C# 调用带有 C++ 标头的 dll

C++ dll 回调C# 程序总结

如何从 c++ 项目中调用用 c# 创建的 dll 文件? [复制]

从 C++ 调用 C# dll

C++ 通过 dll 向 c# 抛出错误

从 C# 调用 C++ dll 函数时出现问题