1

此问题已修复,感谢指出 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函数做了两个请求,分别使用Result2Result3作为输出缓冲区。

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 |

仅供参考,这里是第三个 callResult2再次作为缓冲区: 但是,这并没有神秘地变成胡言乱语。

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 |

我现在很困惑,浪费了一整天的时间,非常感谢任何进一步的指导:)如果我需要提供更多信息,我很乐意这样做,谢谢你的帮助。

4

0 回答 0