Question

I'm trying to make an inter-compiler compatible class in a dll built with mingw that can be used in a Windows VS application. My issue is, my class crashes the moment it tries to initialize a member variable when a function is called from the VS program. Using the STL or making local variables within the same functions works fine.

Unhandled exception at 0x6BEC19FE (test.dll) in ConsoleApplication2.exe: 0xC0000005: Access violation writing location 0x154EB01E.

Simple demonstration:

The dll code

#include <iostream>

class Tester 
{
public:

    virtual void test() = 0;
};

class TesterImp : public Tester
{
public:
    TesterImp(){}
    ~TesterImp(){}

    virtual void test() { 
        int test = 5; // fine
        m_test = 5; // access violation
    }

private:

    int m_test;

};

    extern "C"
    {
        __declspec (dllexport) Tester* Create()
        {
            return new TesterImp();
        }
    }

Main program that loads the dll and calls the test function:

#include <iostream>
#include <Windows.h> 

class Tester 
{
public:

    virtual void test() = 0;
};

typedef Tester* (*createPtr)();

int main(int argc, const char **argv, char * const *envp) {

  HINSTANCE hGetProcIDDLL = LoadLibraryA("test.dll");

  if (hGetProcIDDLL == NULL) {
    std::cout << "could not load the dynamic library" << std::endl;
    return EXIT_FAILURE;
  }

  createPtr ctr = (createPtr)GetProcAddress(hGetProcIDDLL, "Create");
  if (!ctr) {
    std::cout << "could not locate the function" << std::endl;
    return EXIT_FAILURE;
  }

  std::cout << "dll loading success!" << std::endl;

  Tester* testf = ctr();

  std::cout << "Got test class" << std::endl;

  testf->test(); // crash if the member variable is referenced, fine otherwise with local variable initialization or STL use inside the function

  std::cout << "Running dll functions success!" << std::endl;

  return 0;
}

Main program is compiled in debug mode with VS2012 and the dll is built using g++ from mingw -

g++ -shared -o test.dll test.cpp

Could someone explain this behavior for me, please?

Thank you.

Was it helpful?

Solution

You're probably using an older version of MinGW. Up until 4.7.0 (I think), MinGW passed the this pointer on the stack which is different than MSVC's thiscall convention of passing the this pointer in ecx.

Starting with 4.7.0, MinGW uses the same thiscall calling convention as MSVC.

I can also get the example TesterImp::test() function to be called from MSVC successfully by marking both Tester::test() and TesterImp::test() in test.cpp with the __attribute__((thiscall)) attribute. This worked with MinGW 4.6.2, which would cause a crash without the attribute being used.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top