gpt4 book ai didi

c - sprintf 给出未定义的结果

转载 作者:太空宇宙 更新时间:2023-11-04 08:24:31 25 4
gpt4 key购买 nike

我刚刚完成了一个用 C 编写的小 dll。它是第 3 方软件和占星术 dll 之间的接口(interface)。基本上,它根据出生日期、时间、经度和纬度获取沿黄道的占星术宫位经度。因为第 3 方软件需要一个返回字符串,所以我将房屋经度转换为 ascii,并使用 sprintf 将它们与逗号串在一起。如果我在函数“housecusps”中声明返回字符串“retrnString”,我的变量就会损坏(主要是“indx”)。然而,一旦“retrnString”被声明为全局的,它就可以完美地工作。谁能解释一下为什么???

#include <stdio.h>
#include <windows.h>
#include "swephexp.h"
#include "Wave59_SDK.h"

typedef int32 (*JULDAYPTR)(int32, int32, int32, int32, int32, double, int32, double*, char*);
typedef int (*HOUSECUSPSPTR)(double, double, double, int, double*, double*);
char retrnString[96];

BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
DWORD reason /* Reason this function is being called. */ ,
LPVOID reserved /* Not used. */ );

char* __declspec(dllexport) housecusps(WAVE59_DATASTRUCT *price_ptr, int currentptr,
int *int_args,int num_int_args,double *double_args,
int num_double_args,char **string_args,int num_string_args)
{
int32 iyear = int_args[0];
int32 imnth = int_args[1];
int32 iday = int_args[2];
int32 ihr = int_args[3];
int32 imin = int_args[4];
int32 gregflag = SE_GREG_CAL;
double dret[2], cuspArray[13], ascmc[10], julianDays;
char serr[256];
const double zeroSecs = 0;
int hsys = 'P';
int ctr, indx;
JULDAYPTR JulDay;
HOUSECUSPSPTR HouseCusps;

HINSTANCE astrologyDLL = LoadLibrary("c:\\sweph\\bin\\swetrs32.dll");
if (astrologyDLL == NULL)
return "Error loading swedll32.dll";
JulDay = (JULDAYPTR)GetProcAddress(astrologyDLL, "_swe_utc_to_jd@40");
if (JulDay == NULL)
return "Error loading swe_utc_to_jd";
if (JulDay(iyear,imnth,iday,ihr,imin,zeroSecs,gregflag,dret,serr) == ERR)
return serr;
julianDays = dret[1];
HouseCusps = (HOUSECUSPSPTR)GetProcAddress(astrologyDLL, "_swe_houses@36");
if (HouseCusps == NULL)
return "Error loading swe_houses";
/*//Parms:- dret[1] = Julian day in UT, double_args[0] = Latitude, double_args[1] = Longitude.*/
if (HouseCusps(julianDays,double_args[0],double_args[1],hsys,cuspArray,ascmc) == ERR)
return "Error in swe_houses";
indx = 0;
for (ctr = 1;ctr < 13; ctr++)
{
indx += sprintf(retrnString + indx,"%.3f",cuspArray[ctr]);
if (ctr != 12)
indx += sprintf(retrnString + indx ,"%c",',');
}
FreeLibrary(astrologyDLL);
return retrnString;
}

最佳答案

如果你把 char retrnString[96]; 放在 func housecusps(...) 中,当你从那个函数,这个堆栈空间将被清除,这就是它被破坏的原因。

还有一些方法可以从函数中“返回/获取”这样的内容,

  1. 一个全局变量 char retrnString[96]; 就像您所做的一样。

  2. malloc 一个内存来保存内容并返回它,然后记得稍后释放

注意事项:
更好的选择是让函数接受输出缓冲区作为参数。否则,如果调用者使用不同的分配器或不同的内存池,这里的第二个选项(malloc 内部)可能会出现问题。 ---- 来自@Matt McNabb

的建议

使用全局变量作为返回值的主要缺点是您的代码变得不可重入。不能有两个线程同时调用该函数。此外,调用函数一次后,您必须在第二次调用函数之前以第一个值结束,或者在进行第二次调用之前复制第一次调用中的字符串。 ----来自@Jonathan Leffler

的评论

关于c - sprintf 给出未定义的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31307040/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com