dllの関数呼び出し。

ちょいとはまった。

typedef void(__stdcall *DllFunc)(int n);
呼び出される関数の呼び出し規約に従わないと落ちるんだ。

//exe
gcc -g -std=c++0x -Wall test.cpp -o test.exe -lstdc++

#include <windows.h>
#include <iostream>

int main()
{
	HMODULE hmod = LoadLibrary("test.dll");
	if( hmod ) {
		std::cout << "dll found" << std::endl;
		
		typedef void (*DllFunc)(int n); //forgot __stdcall

		DllFunc func = (DllFunc)GetProcAddress(hmod, "PrintTest@4");
		if( func ) {
			std::cout << "process found" << std::endl;

			for(int i = 0; i < 10; ++i) {
				func(i);
			}

		} else {
			std::cout << "process not found" << std::endl;
		}

		FreeLibrary(hmod);
	} else {
		std::cout << "dll not found" << std::endl;
	}

	return 0;
}

//dll
gcc -std=c++0x -shared -g -Wall test_dll.cpp -o test.dll -lstdc++ -mwindows

#include <iostream>
#include <windows.h>
#include <cassert>

extern "C" {

BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
	switch(fdwReason)
	{
	case DLL_PROCESS_ATTACH:
		std::cout << "process attach" << std::endl;
		break;
		
	case DLL_THREAD_ATTACH:
		std::cout << "thread attach" << std::endl;
		break;

	case DLL_THREAD_DETACH:
		std::cout << "thread detach" << std::endl;
		break;

	case DLL_PROCESS_DETACH:
		std::cout << "process detach" << std::endl;
		break;

	default:
		std::cout << "unknown : " << fdwReason << std::endl;
		assert(false);
	}

	return true;
}

//__stdcall
__declspec(dllexport) void __stdcall PrintTest(int n)
{
	std::cout << n << std::endl;
}

};

gdb test
(gdb)run

GNU gdb (GDB) 7.1
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\vc\test\project_dir/test.exe...done.
(gdb) run
Starting program: C:\vc\test\project_dir/test.exe 
[New Thread 11692.0x2db8]
process attach
dll found
process found
0
1
2
3
4

Program received signal SIGSEGV, Segmentation fault.
0x00000005 in ?? ()

最初の5回まで成功するのはなぜなんだ・・・