1

I have C dll with this function:

int CALLINGCONV SMIMESignML(
  const char* pin,
  unsigned long slot,
  const char* szOutputFilePath,
  const char* szFrom,
  const char* szTo,
  const char* szSubject,
  const char* szOtherHeaders,
  const char* szBody,
  const char* szAttachments,
  unsigned long dwFlags,
  int bInitialize
);

CALLINGCONV is _stdcall. And I call it with C++:

#include "stdafx.h"
#include "windows.h"
#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[]) {
  HMODULE lib = LoadLibrary(_T("libname.dll"));
    typedef int(__stdcall  *FNPTR)(const char* pPin, unsigned long slot, 
      const char* pOut, const char* pFrom, const char* pTo, 
      const char* pSubject, const char* pHeaders, const char* pBody, 
      const char* pAttachments, unsigned int flags, int init);
  FNPTR myfunc = (FNPTR)GetProcAddress(lib, "SMIMESignML");
  if (!myfunc) {
    printf("No function!\n");
  } else {
    int code = myfunc(NULL, 0, "", "", "", NULL, NULL, "", "", 0, 0);
    cout << code << endl;
  }
  return 0;
}

The return value (code) is error code, it should be 2 with this parameters, Here it returns 65535 - it is unknown error.

When I run the same code in Pascal:

unit dll;
interface
const
  JNA_LIBRARY_NAME = 'libname.dll';

function SMIMESignML(pPin: PChar; slot: integer; pOut: PChar; pFrom: PChar; pTo: PChar;
  pSubject: PChar; pHeaders: PChar; pBody: PChar; pAttachments: PChar; flags: integer;
  init: integer): integer; stdcall; external JNA_LIBRARY_NAME;
implementation
end.

program Hello;
uses dll;
var 
  code: integer;
begin
  code := SMIMESignML(nil, 0, '', '', '', nil, nil, '' , '', 0, 0);
  writeln(code);
end.

It returns 2, as expected. Why the same calls behave differently? What is the difference?

The OS is Win8x64, for compiling c++ code I use VS2013, the lib.dll is 32 bit.

The question related to this one: Inconsistent results calling DLL from JNA/C versus Pascal but this question doesn't include JNA and JAVA in the scope.

Unfortunately, I don't have sources of the dll library, only some header files.

Community
  • 1
  • 1
  • 1
    Are you compiling the C++ program as 32-bit or 64-bit? – brettwhiteman Jul 16 '15 at 10:20
  • Active solution platform is Win32 – Dmitrii Stebliuk Jul 16 '15 at 10:24
  • How is `CALLINGCONV` defined? – Angew is no longer proud of SO Jul 16 '15 at 10:24
  • it is defined as _stdcall – Dmitrii Stebliuk Jul 16 '15 at 10:26
  • I couldn't help but notice that those signatures do not match- the definition has `const char*` instead of `char*`, and a few `unsigned long` instead of `int`. Given your platform and situation, it shouldn't make a difference, but it could do if you make even slight changes, so I would suggest changing the signature to be an *exact* match. – Puppy Jul 16 '15 at 10:40
  • 1
    There's no obvious mistake in the function pointer declaration. Kinda pointless to not make it match the function declaration, but the types are compatible enough. The proper weapon of choice is a telephone, you really need to know what that error code means. – Hans Passant Jul 16 '15 at 10:53
  • Thank you, I changed the signature of C++ code to match exactly the header, but it doesn't help - the result is still wrong in C++ and right in Pascal. 2Hans: I know almost all the codes, the problem is that Pascal StdCall works fine and with different parameters I get code 0 (=OK), calling the same from C++ always return 0xFFFF, and the function is not working. This parameters and the code 2 it is minimum required parameters for demonstration. – Dmitrii Stebliuk Jul 16 '15 at 11:22
  • Are you positively sure that both programs are loading the same "libname.dll" and that both are running with the same current directory? – rodrigo Jul 16 '15 at 11:35
  • Yes, I checked it again, and put the exes to the same dir, it should not depend on the currDir, and it doesn't. Moreover, if I call this lib from Java JNA, it works the same as in C++ (wrong)... – Dmitrii Stebliuk Jul 16 '15 at 11:43
  • about function and parameters: the function reads the key from smartCard, creates the file and sign it with the key. The last parameter is "auto initialization of card", it's 0, so we should init card manually, we don't do it, so we get error code 2 - Card is not Initialized. If I provide init=1, pinCode as 1st parameter, OutputFile name, Pascal code does everything and returns 0=Ok. C++ code and Java JNA always return 0xFFFF with any parameters... it looks like the function is not calling... – Dmitrii Stebliuk Jul 16 '15 at 11:53
  • As this lib is working in Pascal, I decided just to wrap it in own dll with Pascal. I created the dll lib with function test without input args, and 1 integer output arg: and it returns me wrong code when I call it with Java JNA!!! Moreover, when I call myown lib with Pascal it returns 2!!! I thought the problem is in parameters, but now I completely lost.... – Dmitrii Stebliuk Jul 16 '15 at 12:50
  • Puppy: be careful, C/C++ const and Delphi/Pascal CONST do not always match. In classic Delphi, CONST is equal to C/C++ CONST * (iow const by ref) – Marco van de Voort Jul 16 '15 at 19:54

0 Answers0