我编写了一个使用函数指针数组的 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 类型转换中完全指定类型(而不仅仅是 VECT *)。
我什至尝试在我的 linux 版本中执行此操作。它也崩溃了,所以这不仅仅是 Windows 的问题。
有任何想法吗?