"External exception EO434352" on class instantiation

The below function comes from a C++/CLI project where I'm wrapping a C# library in a C++ library. The solution includes a C++ console app ('Test') along with the two libraries.

The solution builds without error; however when I try to assign 'char *data_out' in the below function I'm running into an exception error with both 'strcpy_s'.

Is there a better way to populate 'data_out'?

Error:
"Unhandled exception at 0x0f3c2fdd in Test.exe: 0xC0000005: Access violation writing location 0x00da7830."


DLL_EXP void GetRevision( char* data_in, char *data_out)
{
APIWrapper wrp;

const char* c = wrp.GetRevisionFunc(data_in);
std::string s = wrp.GetRevisionFunc(c);

strcpy_s(data_out, 200, s.c_str()); // << throws exception. Edit: fixed! But now have a new error

}
Last edited on
So how do you know either pointer is pointing at anything useful to strcpy?

> where I'm wrapping a C# library in a C++ library.
Well that seems like a square peg and a round hole kinda problem.

I'm guessing this is you also, but with far more detail than you've given us to work with.
https://stackoverflow.com/questions/60961498/external-exception-e0434352-on-calling-a-c-cli-wrapper

Did you include <string.h>? That header is where strcpy/strcpy_s are defined. As C library functions, not C++.
Thanks. I was able to resolve the strcpy error (stupid mistake - I had assigned a value to the return variable used to accept 'data_out').

Now it gets tricky.

The whole purpose for this project is to interact with a 3rd party app that requires a Win32 DLL.

So the console app I'm using to test the interaction between my two libraries builds and works without any errors.

However, when I connect to my 3rd party app I'm getting the error "External exception EO434352".

The error occurs at the point where I try to instantiate the APIWrapper class in the 'GetRevision' function (see comments in below code).

The searching I've done on this error suggests that there may be issues in the preprocessor definitions. However I've not had any success with any of the codes changes I've made in that regard.

My guess is that something is amiss in the header; I'm not confident that I've structured the definitions correctly. The problem is that I've yet to find a project that is similar to what I'm trying to do.

The below solution creates the libraries 'LibraryAPI.dll' & 'APIWrapper.dll'.

LibraryAPI.dll:
1
2
3
4
5
6
7
8
9
10
11
12
13
// LibraryAPI.cs

using System;
using System.Windows.Forms;

public class LibraryAPI
{
    public string GetRevisionUtil(string rev)
    {
        MessageBox.Show("CurrentRev: " + rev);
        return "rev_" + rev ;
    }
}


APIWrapper.dll header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// APIWrapper.h

#pragma once

#define DLL_EXP extern "C" __declspec(dllexport)
DLL_EXP void GetRevision(char* data_in, char *data_out);
DLL_EXP void Foo(char* data_in, char *data_out);

class APIWrapperPrivate;

#ifdef WIN32
#define WIN32LIB_API __declspec(dllexport)
#else
#define WIN32LIB_API __declspec(dllimport)
#endif

//class __declspec(dllexport) APIWrapper
class WIN32LIB_API APIWrapper
{
private:  APIWrapperPrivate* _private;

public:
    APIWrapper();
    ~APIWrapper();

    const char* GetRevisionFunc(const char* rev);
};



Please see the comments in the function: GetRevision
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// APIWrapper.cpp

#include "stdafx.h"
#include <msclr\auto_gcroot.h>
#include <string>
#using "LibraryAPI.dll"

#include <msclr\auto_gcroot.h>
#include "APIWrapper.h"

using namespace System::Runtime::InteropServices; // Marshal

DLL_EXP void GetRevision(char* data_in, char *data_out)
{
    MessageBox(NULL, TEXT("MsgBox1"), TEXT("Test"), MB_OK);  // msgbox works!

    APIWrapper wrp;   // << 3rd party app throws error: "External exception EO434352". 
                       // Console test app works fine.   
	  
    MessageBox(NULL, TEXT("MsgBox2"), TEXT("Test"), MB_OK); // never gets here!

    const char *c = wrp.GetRevisionFunc(data_in);

    std::string s = wrp.GetRevisionFunc(c);
    strcpy_s(data_out, 200, s.c_str());

}

const char* APIWrapper::GetRevisionFunc(const char* rev)
{
    System::String^ managedCapi = _private->libraryAPI->GetRevisionUtil(gcnew System::String(rev));
    return (const char*)Marshal::StringToHGlobalAnsi(managedCapi).ToPointer();
}

DLL_EXP void Foo(char* data_in, char *data_out)
{
    // this function works fine with both the console and the 3rd party app.
    int a_size = int(strlen(data_in)); 
    std::string s_a = convertToString(data_in, a_size);
    strcpy_s(data_out,100, s_a.c_str());
}

std::string convertToString(char* a, int size)
{
    int i;
    std::string s = "";
    for (i = 0; i < size; i++) {
        s = s + a[i];
    }
    return s;
}

class APIWrapperPrivate
{
    public: msclr::auto_gcroot<LibraryAPI^> libraryAPI;
};

APIWrapper::APIWrapper()
{
    _private = new APIWrapperPrivate();
    _private->libraryAPI= gcnew LibraryAPI();
}

APIWrapper::~APIWrapper()
{
    delete _private;
}


Console test app:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Test.cpp 

#include <iostream>
#include <stdio.h>

#include "APIWrapper.h"

int main()
{
    APIWrapper wrp;

    char *a = new char[100];
    char *b = new char[200];
    char *d = new char[200];
    
    std::cout << "Enter a string: ";
    std::cin >> a;

    const char* c = wrp.GetRevisionFunc(b); // no errors
    std::cout << c << std::endl;

    GetRevision(a, b);                 // no errors
    std::cout << a << std::endl;
    std::cout << b << std::endl;

    Foo(a, d);                         // no errors
    std::cout << d << std::endl;

    return 0;
}



I should note that the guidance provided by the 3rd party vendor is that it expects the following structure:

1
2
3
#pragma once
#define DLL_EXP	extern "C" __declspec(dllexport)
DLL_EXP void _MY_FUNC(char* data_in, char *data_out);
Last edited on
Topic archived. No new replies allowed.