cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Calling a function in external dll

Former Member
0 Likes
1,503

Hi

I was trying to improve te speed of an application by offloading string manipulations to an external dll. I created a dll with two functions:

replace

fnstringreplace2

The fnstringreplace3 function just returns an int: 42. The replace function returns an int but accepts a string. in this string all '?' are replaced with a space. The declarations in C are as follows:


#ifdef STRINGREPLACE2_EXPORTS

#define STRINGREPLACE2_API __declspec(dllexport)

#else

#define STRINGREPLACE2_API __declspec(dllimport)

#endif

extern "C" STRINGREPLACE2_API int  replace(TCHAR * string);

extern "C" STRINGREPLACE2_API int  fnstringreplace2(void);

The code:


extern "C" STRINGREPLACE2_API int fnstringreplace2(void)

{

  return 42;

}

extern "C" STRINGREPLACE2_API int replace(TCHAR * string) {

  HRESULT res;

  size_t maximalStringSize=1024;

  size_t targetSize;

  res = StringCchLength(string,maximalStringSize,&targetSize);

  for(unsigned int i = 0;i < targetSize ;i++)

  {

  switch (string[i])

  {

  case '?':

  string[i]=' ';

  }

  }

       return 1;

}


The dll seems to work just fine. When I tried to use the dll in powerbuilder I can get the fnstringreplace2 function to work just fine but the replace function doesn't. IT says my arguments are invallid: see attachment.


My declarations in powerbuilder are:


FUNCTION int replace(ref string sayit) LIBRARY "stringreplace2.dll"

FUNCtION int fnstringreplace2() LIBRARY "stringreplace2.dll"

I tried also tried it with char* in the c++ code but this doesn't seem to make any difference.


Any help would be appreciated


Greetings


Vincent Mangelschots


Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Likes

thx to Abdallah ELRHAZOUI for steering my in the right direction. When i changed the call method the functions got renamed in the dll. I didn't have a def file so powerbuilder couldn't find them. I renamed the declaration to the new functionnames (got them using dependency walker) and now it seem to work. Thank you all for helping.

Greetings

Former Member
0 Likes

That's called "name mageling".

However, you should make sure that the caller allocate and deallocate memory. Memory shouldn't be allocated by your *.dll and released from the process which uses your *.dll.

To follow this rule you will save a lot of time hunting down weird problems.

Here's a good explanation why:

c++ - Is it bad practice to allocate memory in a DLL and give a pointer to it to a client app? - Sta...

Answers (4)

Answers (4)

Former Member
0 Likes

When I add __stdcall then powerbuilder doesn't recognize the function anymore (bad runtime function at line x)

Former Member
0 Likes

How do you declare it in PB.

Try :

FUNCTION string functionName(ref string msg) LIBRARY "Your_Full_Path\YourDLL.dll"   ALIAS FOR "functionName;utf8"

Former Member
0 Likes

I don't use the full path but the application opens the dll succesfully (checked it using process explorer and depency walker). I added the alias for but that doesn't change anything

arnd_schmidt
Active Contributor
0 Likes

Do you use a .DEF file?

Former Member
0 Likes

Yes.


Former Member
0 Likes

My function is defined as this in C :

bool my_func (LPCWSTR msg) { }

and in PB :

FUNCTION bool my_func(ref string msg) LIBRARY "mydll.dll"   ALIAS FOR "my_func;utf8"

Regards.

Abdallah.

Former Member
0 Likes

LPCWSTR is a constant.  It wouldn't make sense to pass it as a REF as you can't change the value.  Did you mean LPWSTR?

Former Member
0 Likes

Right. It should be LPWSTR. In my case, I use it but do not change it.

Former Member
0 Likes

Are you sure that the "utf8" part of your function alias is working ?

The documentation states it is ";ansi" or nothing and having tested that with PB11.5, any other value than "ansi" is ignored and the dll function gets utf-16le strings.

arnd_schmidt
Active Contributor
0 Likes

You should add __stdcall.

Some discussion/explanation can be found here:

c# - declspec and stdcall vs declspec only - Stack Overflow

hth

Arnd

Former Member
0 Likes

Did you compile your Dll using the calling convention __Stdcall(/Gz) :

Regards.

Abdallah.

Former Member
0 Likes