Sign in to follow this  

Functor-across-DLL crash...?

This topic is 4598 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to make a program that can be modified by recompiling a major DLL. In the original program I use Functors in numerous places. I figured that since the code for the Functors would be the same between the EXE and DLL, it would be fine to use them in interfaces and pass them straight. However, I downloaded DevC++ /w MinGW to test theories out. I compiled a DLL and the program crashes in the Functors. I've simplified the program into this:
//EXE
//TheClass.h
#ifndef TheClass_h
#define TheClass_h
#include <functor.h>
class TheClass
{
public:
	typedef Functor0<void> TheFunction;
	virtual void SetFunction(TheFunction&)=0;
};
#endif
//main.cpp
#include <iostream>
#include <windows.h>
#include "TheClass.h"
class MyClass : public TheClass
{
protected:
	TheFunction MyFunc;
public:
	virtual void SetFunction(TheFunction& Func)
	{
		MyFunc = Func;
		//MyFunc.CrossDLLBoundaries(Func);
	}
	void CallFunc()
	{
		if(MyFunc) MyFunc();
	}
};
typedef void (*SetFunction)(TheClass&);
void Pause()
{
	char a[256];
	std::cin.getline(a, 256);
}
int main(int Count, char* Args[])
{
	char TheDLLName[256];
	if(Count > 1)
	{//drag & drop
		strcpy_s(TheDLLName, Args[1]);
	}
	else
	{
		std::cout << "Please enter DLL Name:" << std::endl;
		std::cin.getline(TheDLLName, 256);
	}
	HMODULE TheDLL = LoadLibrary(TheDLLName);
	if(TheDLL)
	{
		SetFunction ToCall = (SetFunction)GetProcAddress(TheDLL, "SetFunction");
		if(ToCall)
		{
			MyClass Test;
			ToCall(Test);
			std::cout << "Calling function..." << std::endl;
			Test.CallFunc();
			std::cout << "Function called." << std::endl;
		}
		else
		{
			std::cerr << "Function not found in DLL" << std::endl;
		}
	}
	else
	{
		std::cerr << "Could not load DLL" << std::endl;
	}
	Pause();
	return 0;
}
//DevCPPDLL
#include "..\TheClass.h"
#include <iostream>
void TestFunction()
{
    std::cout << "This is DevCppDLL" << std::endl;
}
template<typename T>
void ShowHex(const T& ToShow)
{
    std::cout << "0x";
    char a[16];
    for(unsigned int i=0; i<sizeof(T); ++i)
    {
        sprintf(a, "%02X", ((char*)&ToShow)[i]);
        std::cout << a;
    }
}
extern "C" __declspec(dllexport) void SetFunction(TheClass&);
void SetFunction(TheClass& a)
{
    TheClass::TheFunction TempFunc;
    MakeFunctor(&TempFunc, TestFunction);
    ShowHex(TempFunc);
    a.SetFunction(TempFunc);
}


If I compile the DevCPPDLL in Visual C++ it runs fine and dandy. If I compile it in MinGW, it crashes. VC shows that SetFunction gets called, but the data is corrupted (Interestingly, it shows that func points to MyClass::__vftable). ShowHex was put in so that I could see how different MinGW and VC set up their data.
MinGW:0xB211C06FCCCCCCCCCCCCCCCC3874C06F
VC   :0x21120110CCCCCCCC3C100110
As you can see, MinGW has an extra 4 bytes in there. Because of this I tried putting in a virtual function to get the desired data--func, callee, and thunk (see the link above). This didn't work how I wanted, the virtual pointer provided by MinGW ended up pointing to MyClass::__vftable instead of Functor0<void>::__vftable (WTF? MyClass is in the EXE, how is it pointing to something it doesn't know about? And it happened every time I tried it, so it wasn't random. Getting it from TheClass& a?), which made it call MyClass::SetFunction instead of Functor0<void>::GetData. VisualC++ worked fine though. I just don't understand what could be going wrong. Any help would be appreciated... [Edited by - Erzengeldeslichtes on May 16, 2005 6:04:58 PM]

Share this post


Link to post
Share on other sites

This topic is 4598 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this