简体   繁体   中英

calling a C++ dll from C# throwing a SEHException

I am trying to call a dll, which I build in C++, from a C# code. However, I am getting the following error:

Exception thrown: 'System.Runtime.InteropServices.SEHException' in dlltest_client.exe An unhandled exception of type 'System.Runtime.InteropServices.SEHException' occurred in dlltest_client.exe External component has thrown an exception.

I am building the C++ dll using a cpp code which in turn imports a header file:

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_;
}

where 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();

this successfully builds dlltest.dll

My C# code that is ought to utilise the dll is

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();
    }
}

You cannot use C++ std::string for unmanaged interop, which is the reason for your DLL throwing an exception.

Instead use pointer to null-terminated character array to pass strings between your C# code and the unmanaged C++ code.

The other error is that the C++ code uses cdecl calling convention, but the C# code assumes stdcall. You need to make the two sides of the interface match, change one to match the other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM