1

Using VS2013, I created a Visual C++ CLR class library, made no changes to project settings. Targeted Framework = .NET 4.5.2.

Referenced System.Windows.Forms and added string to stdafx.h.

ClassLibrary1.h:

#pragma once #if defined DO_EXPORT #define DECLDIR __declspec(dllexport) #else #define DECLDIR __declspec(dllimport) #endif using namespace System; extern "C" { DECLDIR void Foo(); DECLDIR void Foo2a(); DECLDIR void Foo2b(std::string s); } 

ClassLibary1.cpp:

#define DO_EXPORT #include "stdafx.h" #include "ClassLibrary1.h" using namespace System::Windows::Forms; void FooImp() { } void FooImp2(std::string s) { } extern "C" { void Foo() { ::FooImp(); } void Foo2a() { MessageBox::Show("Entered Foo2a"); ::FooImp2(""); MessageBox::Show("Exited Foo2a"); } void Foo2b(std::string s) { MessageBox::Show("Entered Foo2b"); ::FooImp2(s); MessageBox::Show("Exited Foo2b"); } } 

The above code works fine when built into a VS2013 C++ Win32 console app (with string and windows.h added to stdafx.h, and no changes to project settings):

typedef void(*VoidFuncVoid)(void); typedef void(*VoidFuncStr)(std::string); int _tmain(int argc, _TCHAR* argv[]) { VoidFuncVoid _Foo; VoidFuncVoid _Foo2a; VoidFuncStr _Foo2b; HINSTANCE hInstLibrary1 = LoadLibrary(_T("ClassLibrary1.dll")); if (hInstLibrary1) { _Foo = reinterpret_cast<VoidFuncVoid>(GetProcAddress(hInstLibrary1, "Foo")); _Foo(); _Foo2a = reinterpret_cast<VoidFuncVoid>(GetProcAddress(hInstLibrary1, "Foo2a")); _Foo2a(); _Foo2b = reinterpret_cast<VoidFuncStr>(GetProcAddress(hInstLibrary1, "Foo2b")); _Foo2b(""); FreeLibrary(hInstLibrary1); } } 

All Foo calls work great and I get the four message prompts.

But when the same code is built into a VS2008 C++ Win32 console app (with string and windows.h added to stdafx.h, and no changes to project settings), the app crashes in between the two Foo2b message prompts, reporting:

Unhandled exception at 0x0f5433be in ConsoleApp1.exe: 0xC0000005: Access violation reading location 0x002d1000.

What did I miss? What is wrong with the ::FooImp2(s); statement?

4
  • Why are you using C++/CLI if you just want a C++ DLL? Also, 2008 and 2013 are not going to agree on what std::string is, so this will not work. If you need to it to work, stick with a pure C interface. Commented Jan 12, 2016 at 20:06
  • The DLL is an adapter enabling the C++ app to access C# DLLs. Commented Jan 12, 2016 at 20:37
  • You can't use standard C++ library from different versions of Visual Studio, so change to a pure C interface (such as const char * instead of std::string). Commented Jan 12, 2016 at 20:42
  • @crashmstr: I see now how spoiled I have been in the C# ecosystem. Please repost your suggestion as an answer so I can accept it. Thanks for the quick responses. Commented Jan 12, 2016 at 21:10

1 Answer 1

1

To use a library built in Visual Studio that has exported C++ functions with standard library parameters or classes that have standard library members, you essentially must use the same version of Visual Studio for the client. This is because each new version of Visual Studio makes changes to the standard library (and thus the client's idea of what a std::string or std::vector is different from what was compiled into the library).

If you need to have the client and library built with different versions of Visual Studio, the only safe way to do this would be to expose the code you need with a strict C interface (const char * instead of std::string, int ar[], int arCount instead of std::vector<int>).

Sign up to request clarification or add additional context in comments.

3 Comments

Should I at least be able to use std::string inside this adapter DLL as long as its not in its exported interface? When I try a round trip conversion inside a function, the client does not get his original text back. I'm using msclr::interop::marshal_context twice during the round-trip conversion, during which the text is correct right up to the call to myStdStr.c_str() at which point is is no longer the same text.
Yes, you should be able to use std::string internally inside the adapter DLL. If you are having trouble with that, you should probably ask a new question with the code that is having problems and the details.
if you're interested, I just posted "How to convert C++/CLI string to const char*"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.