dll有6个接口函数Dll_SetOption,Dll_GetOption,Dll_InPutData,Dll_CreateImage, Dll_SaveImage,Dll_FreeMem
dllIn.h   //dll内部使用
static DLL_S_SETOPTION g_Option;
static DLL_S_SETOPTION *g_pOption = &g_Option;dll.h
struct DLL_S_SETOPTION {
   ...
}
__declspec(dllexport) int Dll_SetOption(DLL_S_SETOPTION *pOption);
__declspec(dllexport) int Dll_GetOption(DLL_S_SETOPTION *pOption);
__declspec(dllexport) int Dll_InPutData(const unsigned char* pucInputData );
__declspec(dllexport) int Dll_CreateImage(BITMAPFILEHEADER** ppBmfh);
__declspec(dllexport) int Dll_SaveImage(const char* pcFileName);
__declspec(dllexport) int Dll_FreeMem(viod);dll.cppunsigned char * g_pucInputData = new unsigned char[10000];  // *1
BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch (ul_reason_for_call){
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
    break;
    }
    return TRUE;
}int Dll_SetOption(DLL_S_SETOPTION *pOption)
{
    *g_pOption = *pOption;                                 // *2
}int Dll_GetOption(DLL_S_SETOPTION *pOption)
{    *pOption = *g_pOption;   //返回给外面                 // *3
}
int Dll_InPutData(const unsigned char* pucInputData )
{
     memset(g_pucInputData,0,10000);                      // *4
     strcpy((char*)g_pucInputData,(char*)pucInputData);
     .......
  //对g_pucInputData进行处理
}
int Dll_CreateImage(BITMAPFILEHEADER** ppBmfh)
{
  //-->bmp的数据
}
Dll_SaveImage(const char* pcFileName)
{
  //保存为bmp文件
}int Dll_FreeMem(viod)
{
    delete []g_pucInputData;                             // *5
}我的问题是
1:在用户使用dll时,先调用Dll_SetOption先初始化一些其他函数如Dll_CreateImage要使用的数据。一般只设置一次。
   而在后面用户会无数次调用Dll_InPutData,Dll_CreateImage.
   *1处的内存分配的操作是进行一次(在用户程序第一次调用dll中的任一函数时),还是会进行无数次(在用户程序每调用dll中的任一函数时)。
2:在用户调用Dll_FreeMem释放在dll中分配的内存是否合理。*5处
3: 在*2处保存传入的数据在全局结构中,在以后使用。还为*3处返回给外面使用。(在程序中已经可以实现了。)是否是合理的。
4: Dll_SetOption 和Dll_GetOption 的设计方式是否合理。我对于在dll中的内存的管理方式很不清楚。对于*1处有一正在读博的说是不可以的,会进行无数次(在用户程序每调用dll中的任一函数时)。我更糊涂了。

解决方案 »

  1.   

    记得有人说过不要跨Module申请和释放内存.
    我试过了静态调用就可以.动态跨Module的就不行(估计和地址空间映射有关)
      

  2.   

    经实际测试
    *1 只调用一次
    测试程序如下
    #include <windows.h>
    #include <conio.h>int main(int argc, char* argv[])
    {
    printf("Hello World!\n");
    while (getch()) {
    HMODULE hDLL = LoadLibrary("dll.dll"); PROC pFunc = GetProcAddress(hDLL, "MyFunc");
    pFunc();
    pFunc();
    pFunc(); FreeLibrary(hDLL); }
    return 0;
    }DLL的代码
    #pragma comment(linker, "/EXPORT:MyFunc=_MyFunc@0")char* a = new char[1000];BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
     )
    {
        return TRUE;
    }extern "C" __declspec(dllexport) WINAPI MyFunc(void)
    {
    return 0;
    }在分配内存的语句上下断点,只调用了一次
      

  3.   

    2:在用户调用Dll_FreeMem释放在dll中分配的内存是否合理。*5处最好不要这样,用户程序如果多调用一次,不就内存访问违规了,最好自己分配的自己释放,在DllMain中完全可以处理内存分配和释放
      

  4.   

    afc(afc) 
    __declspec(dllexport) int  Dll_GetInputData(unsigned char* pucInputData);我漏了另一个Dll_GetInputData,它是取回曾传入的数据。所以加了
    Dll_FreeMem释放在dll中分配的内存。
      

  5.   

    你这样使用的话,取回数据之后再调用Dll_FreeMem的话此时内存释放了,然后调用DLL的任一函数使用g_pucInputData 都会出错(内存已释放),并且也无法再重新分配内存了,这样程序结构就太混乱了,不如在DllMain中分配或者释放内存,或者是再定义一个Dll_AllocMem函数与DllFreeMem函数配对使用
      

  6.   

    unsigned char * g_pucInputData = new unsigned char[10000];  // *1
    既然你把这个语句写到全局, 那为什么不写成下面的形式呢?
    unsigned char g_pucInputData[10000];这样就不需要释放内存啦,多省事啊?
      

  7.   

    MSDNCalling DLL has two methods: Explicit and Implicit.Different calling methods have different results.
      

  8.   

    简单。用GlobalAlloc()和GlobalFree()代替new和delete就行了。