此问题已修复,感谢指出 typedef 声明中的错误。我在其中缺少 _stdcall 。在挖掘了一些材料之后,它是关于调用约定的,它以不同的方式处理堆栈。我不太确定,但它似乎已修复。谢谢
大家好,大家好,我目前正在开发一个提供串行端口通信的 DLL,然后将结果写入缓冲区。假设 DLL 函数部分是 DLL,而应用程序部分是 EXE。
经过一定的过程,我将能够在 DLL 函数中创建一个字符串。然后我使用 memcpy 将 DLL 中的缓冲区复制到 EXE 提供的 char* 指针
但是,有时复制所有字节也没问题,EXE 可以转储与 DLL 写入的结果一样的结果,但有时它在 DLL 函数部分显示了正确的值,但在 EXE 中,内存部分变得乱码。
我想知道我是否遗漏了一些明显的部分,因为我在内存方面并没有真正的经验以及外部模块如何使用它。
我现在将发布 DLL 部分和 EXE 部分代码供您参考。
DLL 部分:在 VC++ 2012 中编译 dumpstr :从给定地址转储前 20 个字节。 **mp_get_var 通过 .def 文件导出并导出到 DLL **
void dumpstr(char* charC, char* desc) {
printf("\n= S T A R T ===\nDLL Dumping the %s Array...\n", desc);
int i;
for(i=0; i<20; i++) {
printf("%p:%3d | ", charC+i, *(charC+i));
if((i+1)%4==0) printf("\n");
}
printf("\n==E N D====\n");
}
int _stdcall mp_get_var(char* inSI, char* cParam, int paramIndex, char *outSI) {
//std::string returnValue = MyConvert::get_fieldvalue2(inSI,cParam, paramIndex);
printf("ON DLL START, INSI ADDR (%p)\n", inSI);
printf("ON DLL START, OUTSI ADDR (%p)\n", outSI);
dumpstr(outSI, "PREV OUTSI");
//printf("DLL received: %s\n", inSI);
//dumpstr(inSI, "THIS > INSI");
std::string returnValue = "EPTATROPICAL";
memcpy(outSI,returnValue.c_str(),returnValue.length());
//*(outSI + returnValue.length()) = '\0';
//printf("DLL copied outSI: %s\n", outSI);
dumpstr(outSI, "THIS COPIED OUTSI");
printf("ON DLL END, INSI ADDR (%p)\n", inSI);
printf("ON DLL END, OUTSI ADDR (%p)\n", outSI);
return returnValue.length();
}
EXE部分:用Dev-C++编译我使用以下语句导入库:我对DLL函数做了两个请求,分别使用Result2和Result3作为输出缓冲区。
typedef int (*mp_get_var)(char * , char* , int , char *);
int main() {
HINSTANCE hLib = LoadLibrary("MPComsDLL.dll");
MP_GET_VAR = (mp_get_var)GetProcAddress((HMODULE)hLib, "mp_get_var");
sprintf(cRequest, "EPAMTOH");
//using **Result2** char array for result buffer.
returnval = MP_GET_VAR(Result, cRequest, 1, Result2);
printf("ON EXE, OUTSI address : %p", Result2);
printf("%s return length: %d\n", cRequest, returnval);
dumpstr(Result2);
sprintf(cRequest, "MERCHANTID");
//using **Result3** char array for result buffer.
returnval = MP_GET_VAR(Result, cRequest, 1, Result3);
printf("ON EXE, OUTSI address : %p", Result3);
printf("%s return length: %d\n", cRequest, returnval);
dumpstr(Result3);
}
但是,这里是屏幕转储: 对于第一次通话
ON DLL START, INSI ADDR (0028F8B0)
ON DLL START, OUTSI ADDR (0028F680)
= S T A R T ===
DLL Dumping the PREV OUTSI Array...
0028F680: 0 | 0028F681: 0 | 0028F682: 0 | 0028F683: 0 |
0028F684: 0 | 0028F685: 0 | 0028F686: 0 | 0028F687: 0 |
0028F688: 0 | 0028F689: 0 | 0028F68A: 0 | 0028F68B: 0 |
0028F68C: 0 | 0028F68D: 0 | 0028F68E: 0 | 0028F68F: 0 |
0028F690: 0 | 0028F691: 0 | 0028F692: 0 | 0028F693: 0 |
==E N D====
= S T A R T ===
DLL Dumping the THIS COPIED OUTSI Array...
0028F680: 69 | 0028F681: 80 | 0028F682: 84 | 0028F683: 65 |
0028F684: 84 | 0028F685: 82 | 0028F686: 79 | 0028F687: 80 |
0028F688: 73 | 0028F689: 67 | 0028F68A: 65 | 0028F68B: 76 |
0028F68C: 0 | 0028F68D: 0 | 0028F68E: 0 | 0028F68F: 0 |
0028F690: 0 | 0028F691: 0 | 0028F692: 0 | 0028F693: 0 |
==E N D====
ON DLL END, INSI ADDR (0028F8B0)
ON DLL END, OUTSI ADDR (0028F680)
ON EXE, OUTSI address : 0028F680佩 return length: 12
DLL 端第一次调用结束 这是同一地址的 EXE 部分中的转储。
----
Now Dumping the Char Array...
0028F680: 69 | 0028F681: 80 | 0028F682: 84 | 0028F683: 65 |
0028F684: 84 | 0028F685: 82 | 0028F686: 79 | 0028F687: 80 |
0028F688: 73 | 0028F689: 67 | 0028F68A: 65 | 0028F68B: 76 |
0028F68C: 0 | 0028F68D: 0 | 0028F68E: 0 | 0028F68F: 0 |
0028F690: 0 | 0028F691: 0 | 0028F692: 0 | 0028F693: 0 |
EXE部分转储完成,你可以看到它与DLL部分转储相同,所以我认为它工作正常。
然后是下一个调用,它使用Result3作为缓冲区。我看到它的地址来自0028F450
ON DLL START, INSI ADDR (0028F8B0)
ON DLL START, OUTSI ADDR (0028F450)
= S T A R T ===
DLL Dumping the PREV OUTSI Array...
0028F450: 0 | 0028F451: 0 | 0028F452: 0 | 0028F453: 0 |
0028F454: 0 | 0028F455: 0 | 0028F456: 0 | 0028F457: 0 |
0028F458: 0 | 0028F459: 0 | 0028F45A: 0 | 0028F45B: 0 |
0028F45C: 0 | 0028F45D: 0 | 0028F45E: 0 | 0028F45F: 0 |
0028F460: 0 | 0028F461: 0 | 0028F462: 0 | 0028F463: 0 |
==E N D====
= S T A R T ===
DLL Dumping the THIS COPIED OUTSI Array...
0028F450: 69 | 0028F451: 80 | 0028F452: 84 | 0028F453: 65 |
0028F454: 84 | 0028F455: 82 | 0028F456: 79 | 0028F457: 80 |
0028F458: 73 | 0028F459: 67 | 0028F45A: 65 | 0028F45B: 76 |
0028F45C: 0 | 0028F45D: 0 | 0028F45E: 0 | 0028F45F: 0 |
0028F460: 0 | 0028F461: 0 | 0028F462: 0 | 0028F463: 0 |
==E N D====
ON DLL END, INSI ADDR (0028F8B0)
ON DLL END, OUTSI ADDR (0028F450)
ON EXE, OUTSI address : 0028F450MERCHANTID return length: 12
奇怪从这里开始,我在DLL中看到0028F450,应该是
69,80,84,65,84,82,79,80,73,67,65,76
但是... exe中的dump变成了这样,但是变成了
0,0,68,0,83,-12,40,0,0,0,0,0
转储仍然在地址0028F450
----
Now Dumping the Char Array...
0028F450: 0 | 0028F451: 0 | 0028F452: 68 | 0028F453: 0 |
0028F454: 83 | 0028F455:-12 | 0028F456: 40 | 0028F457: 0 |
0028F458: 0 | 0028F459: 0 | 0028F45A: 0 | 0028F45B: 0 |
0028F45C: 0 | 0028F45D: 0 | 0028F45E: 0 | 0028F45F: 0 |
0028F460: 0 | 0028F461: 0 | 0028F462: 0 | 0028F463: 0 |
仅供参考,这里是第三个 call,Result2再次作为缓冲区: 但是,这并没有神秘地变成胡言乱语。
ON DLL START, INSI ADDR (0028F8B0)
ON DLL START, OUTSI ADDR (0028F680)
= S T A R T ===
DLL Dumping the PREV OUTSI Array...
0028F680: 69 | 0028F681: 80 | 0028F682: 84 | 0028F683: 65 |
0028F684: 84 | 0028F685: 82 | 0028F686: 79 | 0028F687: 80 |
0028F688: 73 | 0028F689: 67 | 0028F68A: 65 | 0028F68B: 76 |
0028F68C: 0 | 0028F68D: 0 | 0028F68E: 0 | 0028F68F: 0 |
0028F690: 0 | 0028F691: 0 | 0028F692: 0 | 0028F693: 0 |
==E N D====
= S T A R T ===
DLL Dumping the THIS COPIED OUTSI Array...
0028F680: 69 | 0028F681: 80 | 0028F682: 84 | 0028F683: 65 |
0028F684: 84 | 0028F685: 82 | 0028F686: 79 | 0028F687: 80 |
0028F688: 73 | 0028F689: 67 | 0028F68A: 65 | 0028F68B: 76 |
0028F68C: 0 | 0028F68D: 0 | 0028F68E: 0 | 0028F68F: 0 |
0028F690: 0 | 0028F691: 0 | 0028F692: 0 | 0028F693: 0 |
==E N D====
ON DLL END, INSI ADDR (0028F8B0)
ON DLL END, OUTSI ADDR (0028F680)
TERMINALID return length: 12
----
Now Dumping the Char Array...
0028F680: 69 | 0028F681: 80 | 0028F682: 84 | 0028F683: 65 |
0028F684: 84 | 0028F685: 82 | 0028F686: 79 | 0028F687: 80 |
0028F688: 73 | 0028F689: 67 | 0028F68A: 65 | 0028F68B: 76 |
0028F68C: 0 | 0028F68D: 0 | 0028F68E: 0 | 0028F68F: 0 |
0028F690: 0 | 0028F691: 0 | 0028F692: 0 | 0028F693: 0 |
我现在很困惑,浪费了一整天的时间,非常感谢任何进一步的指导:)如果我需要提供更多信息,我很乐意这样做,谢谢你的帮助。