Q:Crashed after calling DLL function 
Author Message
 Q:Crashed after calling DLL function

I used LoadLibrary and GetProcAddress to find a DLL's function. It worked
fine at this step. The problem was after calling that function, the
application will fail with "access violation" message. These two program
(.exe and .dll) were generated by VC's new projects function. I tried to
build .exe program with command line mode and worked fine. Does anybody know
why?

#include <windows.h>
#include <iostream>
using namespace std ;

typedef LRESULT (CALLBACK * TESTFUNCTION)( SIZEL, SIZEL, LPVOID, DWORD ) ;
int main( void )
{
 TESTFUNCTION testFunction ;
 HINSTANCE hFile ;
 // Handle .dll file
 hFile = LoadLibrary( TEXT( "DllMain.dll" ) ) ;
 // call dll file AddValue of function
 testFunction = (TESTFUNCTION)GetProcAddress( hFile, "TestFunction" ) ;
 if(!hFile || testFunction == NULL )
 {
  FreeLibrary(hFile) ;
  cout << "Cannot Handle DllMain.dll : " << GetLastError() << endl ;
  return 0 ;
 }
    // Creat memory-mapped file
    TCHAR szTmpPath[ MAX_PATH + 1 ];
    TCHAR szTmpFile[ MAX_PATH + 1 ];
    /* Create temporary file for mapping. */
    GetTempPath ( sizeof( szTmpPath ), szTmpPath );
    GetTempFileName( szTmpPath, TEXT( "TAKA" ), 0, szTmpFile );
    HANDLE hTempFile = CreateFile( szTmpFile, GENERIC_WRITE | GENERIC_READ,
                                   FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
                                   FILE_ATTRIBUTE_TEMPORARY, NULL );
    if( hTempFile == INVALID_HANDLE_VALUE ){
        return 1;
    }
    DWORD dwWroteBytes;
    WriteFile( hTempFile, TEXT( "TEXT FOR TEST" ), 26 + 1,  &dwWroteBytes,
NULL );
    HANDLE hMMFile = CreateFileMapping( hTempFile, NULL, PAGE_READWRITE, 0,
                                        0x0140000, NULL );
    if( hMMFile == NULL ){
        CloseHandle( hTempFile );
        return 1;
    }
    // Map view of the entire file
    LPVOID lpBuffer = MapViewOfFile( hMMFile, FILE_MAP_WRITE, 0, 0, 0 );
    if( lpBuffer == NULL ){
        CloseHandle( hMMFile );
        CloseHandle( hTempFile );
        return 1;
    }
    SIZEL slPrintSize, slBitmapSize;
    DWORD dwCopies;
    // Initial values
    slPrintSize.cx = 1024;
    slPrintSize.cy = 1280;
    slBitmapSize.cx = 986;
    slBitmapSize.cy = 8475;
    dwCopies = 13;
    LRESULT lResult = testFunction( slPrintSize, slBitmapSize, lpBuffer,
dwCopies );
    UnmapViewOfFile( lpBuffer );
    CloseHandle( hMMFile );
    CloseHandle( hTempFile );
 return 0;

Quote:
}

#include <windows.h>
#include <iostream>
using namespace std;

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
    return TRUE;

Quote:
}

extern "C"

__declspec(dllexport) LRESULT __cdecl TestFunction( SIZEL
slPrintablePaperSize,
                                                    SIZEL slBitmapDimension,
                                                    LPVOID pBitmapBuffer,
                                                    DWORD dwCopies  )
{
    static TCHAR tcBuffer[ 4096 ];
    wsprintf( tcBuffer, TEXT( "Printable X: %d\nPrintable Y: %d\nBitmap X:
%d\nBitmap Y: %d\nCopies: %d\nContents address: %x\n" ),
                        slPrintablePaperSize.cx,
                        slPrintablePaperSize.cy,
                        slBitmapDimension.cx,
                        slBitmapDimension.cy,
                        dwCopies,
                        pBitmapBuffer );

    wcout << tcBuffer << endl;
    return TRUE;

Quote:
}
};



Tue, 01 Jul 2003 09:42:54 GMT  
 Q:Crashed after calling DLL function
Greets,

    One apparent problem is your inconsistency with calling convention.  In
your typedef, you use CALLBACK which adds the __stdcall modifier to the
function declaration.  In your actual definition for the function, you
declare it as __cdecl.  Both __cdecl and __stdcall calling conventions push
arguments from right to left on the stack, however, in the case of
__stdcall, the called function pops the stack arguments, whereas in the case
of __cdecl, the arguments are popped after the function call has returned.
(This, by the way, is why functions with variable length argument lists are
all inherently __cdecl regardless of the calling convention specification,
since the number of bytes to pop is known by the compiler and done after the
function returns.)

    Another possible future problem can be the WriteFile() call with the
string literal and buffer size that is not commensurate with the size of the
string.  I notice that you attempt to write out 26+1 bytes for a string that
is only 13 characters plus a null byte if you are *not* compiling for
unicode.  If you need the explicit size of a string literal for both unicode
and non-unicode builds, including the space for the null terminator, you can
use the following:

    sizeof(TEXT("TEXT FOR TEST"));

Regards,

Joe


Quote:
> I used LoadLibrary and GetProcAddress to find a DLL's function. It worked
> fine at this step. The problem was after calling that function, the
> application will fail with "access violation" message. These two program
> (.exe and .dll) were generated by VC's new projects function. I tried to
> build .exe program with command line mode and worked fine. Does anybody
know
> why?

> #include <windows.h>
> #include <iostream>
> using namespace std ;

> typedef LRESULT (CALLBACK * TESTFUNCTION)( SIZEL, SIZEL, LPVOID, DWORD ) ;
> int main( void )
> {
>  TESTFUNCTION testFunction ;
>  HINSTANCE hFile ;
>  // Handle .dll file
>  hFile = LoadLibrary( TEXT( "DllMain.dll" ) ) ;
>  // call dll file AddValue of function
>  testFunction = (TESTFUNCTION)GetProcAddress( hFile, "TestFunction" ) ;
>  if(!hFile || testFunction == NULL )
>  {
>   FreeLibrary(hFile) ;
>   cout << "Cannot Handle DllMain.dll : " << GetLastError() << endl ;
>   return 0 ;
>  }
>     // Creat memory-mapped file
>     TCHAR szTmpPath[ MAX_PATH + 1 ];
>     TCHAR szTmpFile[ MAX_PATH + 1 ];
>     /* Create temporary file for mapping. */
>     GetTempPath ( sizeof( szTmpPath ), szTmpPath );
>     GetTempFileName( szTmpPath, TEXT( "TAKA" ), 0, szTmpFile );
>     HANDLE hTempFile = CreateFile( szTmpFile, GENERIC_WRITE |
GENERIC_READ,
>                                    FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
>                                    FILE_ATTRIBUTE_TEMPORARY, NULL );
>     if( hTempFile == INVALID_HANDLE_VALUE ){
>         return 1;
>     }
>     DWORD dwWroteBytes;
>     WriteFile( hTempFile, TEXT( "TEXT FOR TEST" ), 26 + 1,  &dwWroteBytes,
> NULL );
>     HANDLE hMMFile = CreateFileMapping( hTempFile, NULL, PAGE_READWRITE,
0,
>                                         0x0140000, NULL );
>     if( hMMFile == NULL ){
>         CloseHandle( hTempFile );
>         return 1;
>     }
>     // Map view of the entire file
>     LPVOID lpBuffer = MapViewOfFile( hMMFile, FILE_MAP_WRITE, 0, 0, 0 );
>     if( lpBuffer == NULL ){
>         CloseHandle( hMMFile );
>         CloseHandle( hTempFile );
>         return 1;
>     }
>     SIZEL slPrintSize, slBitmapSize;
>     DWORD dwCopies;
>     // Initial values
>     slPrintSize.cx = 1024;
>     slPrintSize.cy = 1280;
>     slBitmapSize.cx = 986;
>     slBitmapSize.cy = 8475;
>     dwCopies = 13;
>     LRESULT lResult = testFunction( slPrintSize, slBitmapSize, lpBuffer,
> dwCopies );
>     UnmapViewOfFile( lpBuffer );
>     CloseHandle( hMMFile );
>     CloseHandle( hTempFile );
>  return 0;
> }

> #include <windows.h>
> #include <iostream>
> using namespace std;

> BOOL APIENTRY DllMain( HANDLE hModule,
>                        DWORD  ul_reason_for_call,
>                        LPVOID lpReserved
>       )
> {
>     return TRUE;
> }

> extern "C"

> __declspec(dllexport) LRESULT __cdecl TestFunction( SIZEL
> slPrintablePaperSize,
>                                                     SIZEL
slBitmapDimension,
>                                                     LPVOID pBitmapBuffer,
>                                                     DWORD dwCopies  )
> {
>     static TCHAR tcBuffer[ 4096 ];
>     wsprintf( tcBuffer, TEXT( "Printable X: %d\nPrintable Y: %d\nBitmap X:
> %d\nBitmap Y: %d\nCopies: %d\nContents address: %x\n" ),
>                         slPrintablePaperSize.cx,
>                         slPrintablePaperSize.cy,
>                         slBitmapDimension.cx,
>                         slBitmapDimension.cy,
>                         dwCopies,
>                         pBitmapBuffer );

>     wcout << tcBuffer << endl;
>     return TRUE;
> }

> };



Wed, 02 Jul 2003 22:46:35 GMT  
 Q:Crashed after calling DLL function
Well at a guess because you have mismatched calling conventions between the
function in the DLL end the call in the EXE.
In the EXE you have:
Quote:
> typedef LRESULT (CALLBACK * TESTFUNCTION)( SIZEL, SIZEL, LPVOID, DWORD ) ;
>  TESTFUNCTION testFunction ;

In the DLL you have:
Quote:
> __declspec(dllexport) LRESULT __cdecl TestFunction( SIZEL
> slPrintablePaperSize,
>                                                     SIZEL
slBitmapDimension,
>                                                     LPVOID pBitmapBuffer,
>                                                     DWORD dwCopies  )

Note you have __cdecl in the DLL but not the EXE.
Without knowing the rest of the project settings it is difficult to say if
this is significant or not. ( i.e. I cant be bothered to try it)
You should set /GZ (catch release errors in debug build) in your compile
options as it checks for calling convention mismatches among other things.

Nick

--


Quote:
> I used LoadLibrary and GetProcAddress to find a DLL's function. It worked
> fine at this step. The problem was after calling that function, the
> application will fail with "access violation" message. These two program
> (.exe and .dll) were generated by VC's new projects function. I tried to
> build .exe program with command line mode and worked fine. Does anybody
know
> why?

> #include <windows.h>
> #include <iostream>
> using namespace std ;

> typedef LRESULT (CALLBACK * TESTFUNCTION)( SIZEL, SIZEL, LPVOID, DWORD ) ;
> int main( void )
> {
>  TESTFUNCTION testFunction ;
>  HINSTANCE hFile ;
>  // Handle .dll file
>  hFile = LoadLibrary( TEXT( "DllMain.dll" ) ) ;
>  // call dll file AddValue of function
>  testFunction = (TESTFUNCTION)GetProcAddress( hFile, "TestFunction" ) ;
>  if(!hFile || testFunction == NULL )
>  {
>   FreeLibrary(hFile) ;
>   cout << "Cannot Handle DllMain.dll : " << GetLastError() << endl ;
>   return 0 ;
>  }
>     // Creat memory-mapped file
>     TCHAR szTmpPath[ MAX_PATH + 1 ];
>     TCHAR szTmpFile[ MAX_PATH + 1 ];
>     /* Create temporary file for mapping. */
>     GetTempPath ( sizeof( szTmpPath ), szTmpPath );
>     GetTempFileName( szTmpPath, TEXT( "TAKA" ), 0, szTmpFile );
>     HANDLE hTempFile = CreateFile( szTmpFile, GENERIC_WRITE |
GENERIC_READ,
>                                    FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
>                                    FILE_ATTRIBUTE_TEMPORARY, NULL );
>     if( hTempFile == INVALID_HANDLE_VALUE ){
>         return 1;
>     }
>     DWORD dwWroteBytes;
>     WriteFile( hTempFile, TEXT( "TEXT FOR TEST" ), 26 + 1,  &dwWroteBytes,
> NULL );
>     HANDLE hMMFile = CreateFileMapping( hTempFile, NULL, PAGE_READWRITE,
0,
>                                         0x0140000, NULL );
>     if( hMMFile == NULL ){
>         CloseHandle( hTempFile );
>         return 1;
>     }
>     // Map view of the entire file
>     LPVOID lpBuffer = MapViewOfFile( hMMFile, FILE_MAP_WRITE, 0, 0, 0 );
>     if( lpBuffer == NULL ){
>         CloseHandle( hMMFile );
>         CloseHandle( hTempFile );
>         return 1;
>     }
>     SIZEL slPrintSize, slBitmapSize;
>     DWORD dwCopies;
>     // Initial values
>     slPrintSize.cx = 1024;
>     slPrintSize.cy = 1280;
>     slBitmapSize.cx = 986;
>     slBitmapSize.cy = 8475;
>     dwCopies = 13;
>     LRESULT lResult = testFunction( slPrintSize, slBitmapSize, lpBuffer,
> dwCopies );
>     UnmapViewOfFile( lpBuffer );
>     CloseHandle( hMMFile );
>     CloseHandle( hTempFile );
>  return 0;
> }

> #include <windows.h>
> #include <iostream>
> using namespace std;

> BOOL APIENTRY DllMain( HANDLE hModule,
>                        DWORD  ul_reason_for_call,
>                        LPVOID lpReserved
>       )
> {
>     return TRUE;
> }

> extern "C"

> __declspec(dllexport) LRESULT __cdecl TestFunction( SIZEL
> slPrintablePaperSize,
>                                                     SIZEL
slBitmapDimension,
>                                                     LPVOID pBitmapBuffer,
>                                                     DWORD dwCopies  )
> {
>     static TCHAR tcBuffer[ 4096 ];
>     wsprintf( tcBuffer, TEXT( "Printable X: %d\nPrintable Y: %d\nBitmap X:
> %d\nBitmap Y: %d\nCopies: %d\nContents address: %x\n" ),
>                         slPrintablePaperSize.cx,
>                         slPrintablePaperSize.cy,
>                         slBitmapDimension.cx,
>                         slBitmapDimension.cy,
>                         dwCopies,
>                         pBitmapBuffer );

>     wcout << tcBuffer << endl;
>     return TRUE;
> }

> };



Thu, 03 Jul 2003 05:14:24 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Qs on Function Call on Array

2. VB callback function, called from a VC DLL, crashes

3. Calling an exported function of a dll which are exported Stdcall calling convention

4. Call Back Functions call from within a DLL

5. Calling DLL functions without known function name, parameter-list until run-time

6. Call CreateThread function in NT 4.0, it cause crash Explorer for Shell Extionsion

7. crash during debugging on entering function call

8. Calling a dll function from another dll.

9. What can cause ::CreateWindowEx -function call to crash?

10. Call DLL function from DLL

11. Need a C-Dll to call functions in a C++ Dll

12. DLL function calling problems (explicit - only knowing function name at runtime)

 

 
Powered by phpBB® Forum Software