我已经在其他问题中搜索了几天,但没有找到任何符合我的情况的答案,所以如果它重复,我很抱歉,在这种情况下,请指出解决方案。
我有一个 Delphi 7 应用程序,它尝试通过将
TPanel
的属性 Handle
传递给 C++ DLL(用 Visual Studio 2008 编写),将 OpenGL 场景渲染到 TPanel
中。这是 DLL 函数契约:
#pragma once
#ifdef QMM_EXPORTS
#define QMM_API __declspec(dllexport)
#else
#define QMM_API __declspec(dllimport)
#endif
extern "C" QMM_API int getParam (int key);
extern "C" QMM_API float getParamF (int key);
extern "C" QMM_API char *getParamS (int key);
#include <gl/gl.h>
extern "C" QMM_API int setGlRenderTo (HWND hwnd);
extern "C" QMM_API void glRenderTest ();
DLL代码如下所示:
int setGlRenderTo (HWND hwnd) {
GLuint PixelFormat;
doLog('D',"setGlRenderTo(): start (hwnd=%i)", hwnd->unused);
if (hwnd != NULL && currHWND == hwnd) {
doLog('W', "setGlRenderTo(): hwnd == currHWND, ignoring");
return 0;
}
if (currRC != NULL) {
doLog('D', "setGlRenderTo(): releasing currRC...");
wglMakeCurrent(NULL,NULL);
wglDeleteContext(currRC);
currHWND = NULL;
}
if (currDC != NULL) {
doLog('D', "setGlRenderTo(): releasing currDC...");
ReleaseDC(currHWND,currDC);
currHWND = NULL;
}
currDC = GetDC(hwnd);
if (!currDC) {
doLog('E', "setGlRenderTo(): Failed to get a valid DC, aborting");
return 1;
}
currHWND = hwnd;
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24,
8,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
if (!(PixelFormat=ChoosePixelFormat(currDC,&pfd))) {
doLog('E', "setGlRenderTo(): Failed to get a valid pixel format, aborting");
return 1;
}
if (!SetPixelFormat(currDC, PixelFormat, &pfd)) {
doLog('E', "setGlRenderTo(): Failed to set pixel format, aborting");
return 1;
}
if (!(currRC=wglCreateContext(currDC))) {
doLog('E', "setGlRenderTo(): Failed to create OpenGL rendering context, aborting");
return 1;
}
if (!wglMakeCurrent(currDC,currRC)) {
doLog('E', "setGlRenderTo(): Failed to switch to OpenGL rendering context, aborting");
return 1;
}
return 0;
}
在 Delphi 7 端,我的 DLL 调用映射如下:
function setGlRenderTo (handler : HWND) : integer; external 'qmm.dll';
当我尝试创建 DC 上下文时(在
currDC = GetDC(hwnd);
行),我的 DLL 代码失败。
我已经尝试将 Delphi 端的类型更改为
LongWord
,以及 DLL 中的 unsigned int
。另外,我尝试将其传递为 Integer
(Delphi 端)和 int
(C++ 端)。任何测试均未成功。
在 C++ 方面,函数声明中没有显式指定调用约定,因此 C++ 编译器可能默认为
__cdecl
,这是大多数 C++ 编译器使用的默认调用约定。
在Delphi方面,您没有对导入的DLL函数指定任何调用约定,因此Delphi编译器将默认为
register
,这与Visual Studio支持的任何调用约定都不兼容。
因此,在 Delphi 端的声明中添加
cdecl
:
function setGlRenderTo (handler : HWND) : integer; cdecl; external 'qmm.dll';
^^^^^