一共不超过10行,麻烦好心人帮看下,十分感谢...
我用VC6.0写了一个关于socket传送文件的DLL,在delphi调用这个DLL,
DLL中有个函数原形如下:
void _stdcall SendFileThread(LPCTSTR lpszFileName)     //导出的函数,接收文件名,
                                                               //并启动1个线程开始传送这个文件
{
    char buf[100];                     //以下称此行为第一行
    sprintf(buf, "%s",lpszFileName);   //以下称此行为第二行
    HANDLE hThread = CreateThread(NULL, 0, SendFilePro, LPVOID(buf),0,NULL);
    //1.上一行第4个参数如果写成LPVOID(lpszFileName),结果在线程函数也是接收乱码
    CloseHandle(hThread);
    AfxMessageBox(lpszFileName);//气我吐血的一行代码...以下简称此行代码为[error行]
    //2.如果这里测试[error行],文件名相当准确,气死我了,
    //3.如果加上[error行],不管我怎么写第4个参数,在线程函数都能收到正确文件名,不会乱码
    //4.如果去掉[error行],不管我怎么写第4个参数,在线程函数都能收到乱码
}DWORD WINAPI SendFilePro(LPVOID lpParameter)           //这是线程函数,DLL内部函数
{
    LPCTSTR lpszFileName = (LPCTSTR)lpParameter;
    AfxMessageBox(lpszFileName); 
    //5.这行测试是否正确收到文件名,结果错误,是乱码    //这行以下不用看了,传送文件过程,经测试无错
     ...........
     CFile file(lpszFileName,CFile::modeRead);       
    ..........
}在没有[error行]情况下,我把buf设成公共变量,或pbuf = new char[100];结果不会收到乱码。
当我用到new 以后,我想到会在线程函数delete它的6.但是啊,delphi调用这个函数传进的字串,是谁释放的啊?//迷糊到这里啦....
delphi 调用代码如下
procedure TFormMain.BtnSendFileClick(Sender: TObject);
var
  vStrFileName: String; 
  vFileName: PChar;
begin
  if OpenDialog1.Execute then
  begin
    vStrFileName := ExtractFileName(OpenDialog1.FileName);
    //vFileName := AllocMem(100);
    vFileName := pchar(vStrFileName);
    SendFileThread(vFileName);              //发送文件(文件名不包含路径)
  end;
end;7.请教一下,在这种情形下,//vFileName := AllocMem(100);用不用加?不加也不会出错好象
8.这里的PChar是由谁释放的,啥时候释放的?如果不释放,就算一秒传1个文件名,一天下来系统也受不了吧?
9.为啥我取文件名的时候,不用带路径啊,不带路径,系统也能正确找到文件,在VC代码中也不用带路径的.
10.vc局部变量char buf[100]; 函数结束后,buf是自动释放了吗?我保留它的指针也不行吗?
11.如果这里的pchar释放早了,DLL还会收到参数吗?

解决方案 »

  1.   

    楼主最好把void _stdcall SendFileThread(LPCTSTR lpszFileName)能数定义成char * lpszFilename使用标准的C
    这样你在delphi中调用时也不用new一个内存出来,
    在DLL内部函数中
        char buf[100];                    //以下称此行为第一行 
        sprintf(buf, "%s",lpszFileName);  //以下称此行为第二行 
        HANDLE hThread = CreateThread(NULL, 0, SendFilePro, LPVOID(buf),0,NULL);
    你这个buf还没进入线程就释放了,所以这里你最好new一个指针出来,把文件名存入这个指针,再传到线程中,如:char * buf = new[100]; 
        sprintf(buf, "%s",lpszFileName);  //以下称此行为第二行 
        HANDLE hThread = CreateThread(NULL, 0, SendFilePro, LPVOID(buf),0,NULL);
    在线程中
    DWORD WINAPI SendFilePro(LPVOID lpParameter)          //这是线程函数,DLL内部函数 
    {
    char * filename = (char*)lpParameter;
    delete [] filename;
    }
      

  2.   

    Dephi传进去的,由Dephi自己控制
    buf new出来以后,可以在线程返回了以后,自己再delete.
      

  3.   


    对,如果dephi不能删除,可以提供接口给dephi,然后,dephi调用删除
      

  4.   

    谢谢以上回答,解决我很大问题,这个问题麻烦再看一下,
    var 
      vStrFileName: String; 
      vFileName: PChar;     //vFileName := AllocMem(100); 
        vFileName := pchar(vStrFileName); 1. 这里的vFileName: PChar; 用不用手工释放?它好像局部量数,我记忆中局部变量不用手工释放,疑问在此啊?
    1.5 如果不用手工释放,它是何时释放的?
    2. //vFileName := AllocMem(100); 这句加与不加在释放的时候有何不同????我在delphi版也提此问了,但没人回啊,只好再发一次..
      

  5.   

    下午困蒙瞪了,问题自己没考虑清楚,也没有问清楚,下班步行回家,得正解如下:
    我本意是想问局部变量做为参数进入DLL后的生存期问题.
    局部变量生存期的定义在进入DLL中依然成立,也就是说进入DLL后,局部变量依然存在,但进入线程当然就不行了,
    在DLL中对于传进来的局部变量,只要你能用,可以放心大但地用(通常用不上^^),不必担心内存泄漏,外部那个局部变量所在函数结束,它自然释放了
    本贴有3个函数,按顺序如下:
    1. delphi 调用代码如下 
    procedure TFormMain.BtnSendFileClick(Sender: TObject);   //产生局部变量[vFileName: PChar;] 并做为参数传入DLL
    2. void _stdcall SendFileThread(LPCTSTR lpszFileName)    //DLL导出的函数,
    3.DWORD WINAPI SendFilePro(LPVOID lpParameter)           //这是线程函数,由上一个函数启动函数1的局部变量在函数2中是可以找到的,也可以正常使用,函数2只管用,不用管其释放(虽然函数2是DLL中的一个函数),
    当函数2再把它传到函数3时,就不行了,因为函数3是线程,再能用就出鬼了...
    函数2启动线程函数3后,正常结束,导至函数1结束,函数1结束导致局部变量[vFileName: PChar;]释放 问题拆开来,我都明白,合到一起我就迷糊啦..
    头一次跨语言写socket DLL,满足我小小的虚荣心(反正你们不认识我^ ^),今天暂不结贴,明天上班后结束,祝大家2009工作顺心~
    关于本贴6层问题,详细见http://topic.csdn.net/u/20090106/16/93356917-bf28-4f29-9c79-0f533f362bd8.html,(6楼回答很完美)我在那又扔了100分,汗~
      

  6.   

    函数返回后,字符串被释放了,所以才出错。
    你可以把char buf[100]改成char* buf = new char[100],并在线程中释放。