【发布时间】:2013-06-14 14:46:40
【问题描述】:
我编写了一个使用函数指针数组的 C 程序。这 函数既在我的程序内部,也在可加载的 DLL 中。我的问题来了 当我尝试使用来自 C++ 程序的 DLL 时。这里有一个简化的 C++ (DLL) 程序中的代码片段:
#ifdef __cplusplus
#define EXPORT extern "C" __declspec(dllexport)
#else
#define EXPORT __declspec(dllexport)
#endif
typedef struct { float x,y,z; } VECT;
EXPORT VECT norm(OBJECT *obj, RAY ray, float t, VECT *pt, RGB *col)
{
VECT npt;
...
*pt = npt; /* give pt a new value */
...
}
问题是当我尝试对 pt 做任何事情时它就会崩溃。它不是 NULL,但如果我尝试写入它甚至只是访问它的成员,它 崩溃。我已经通过将 C++ 代码转换为 C 来解决这个问题,但是 我真的很想知道为什么会崩溃。如果我尝试 访问 pt,程序运行良好(除了缺少 会带有正确的pt)。顺便说一句,这是另一个奇怪的事情 - 当我在现在的 C DLL 代码中执行以下操作时:
EXPORT VECT norm(OBJECT *obj, RAY ray, float t, VECT *pt, RGB *col)
它崩溃了。但如果我这样做:
EXPORT VECT norm(obj, ray, t, pt, col)
OBJECT *obj;
VECT *pt;
RAY ray;
float t;
RGB *col;
它不会崩溃。有没有办法让 C++ 接受第二种方式 指定参数?
额外信息,以备不时之需...我加载 DLL 函数:
typedef struct Funcs
{
int (*inter)();
VECT (*normal)();
} FUNCS;
/*
I've also tried:
typedef VECT (WINAPI *FNORMAL)(OBJECT *obj, RAY ray, float t, VECT *pt, RGB *col);
(FNORMAL)GetProcAddress...
*/
funcs[i].normal = (VECT *)GetProcAddress(dll2, "norm");
if (funcs[i].normal == NULL) { printf("Error: No norm procedure in '%s'\n", objstr); quit(); }
并通过以下方式调用他们:
hit.normal = funcs[p->type].normal(p, ray, mint, &pt, &colm);
我已经尝试在 GetProcAddress 类型转换。
我什至尝试在我的 linux 版本中执行此操作。它也崩溃了,所以它不是 仅 Windows 的问题。
有什么想法吗?
【问题讨论】:
-
当它崩溃时,
pt的值在调用者的堆栈帧中与在 DLL/共享库中的值是否相同? -
什么是
normal。请出示声明。实际上向我们展示了您传递的参数的声明。此外,GetProcAddress的演员阵容看起来很假。 -
有没有办法让 C++ 接受第二种指定参数的方式? 不,没有,你提出这个问题的事实是一个令人担忧的迹象。这类问题很容易解决。但是不要像无头鸡一样到处乱跑,随意尝试并选择不会崩溃的第一件事。了解问题。然后解决它。正确。
-
@Useless (指针的)值不一样。我现在在linux上,所以我不得不尝试使用linux版本。
-
@DavidHeffernan 我不确定您指的是哪个“正常”,但这是其中之一: typedef struct Funcs { int (*inter)(); VECT (*正常)(); } 功能;
标签: c++ c dll parameters crash