Posted: 31st Jan 2019 10:05
So this wee code snippet example uses the strings dll library (Ian M's matrix1 utils plugin) and gets an input string i.e. "test" and converts it to upper case using the plugin function "FastUpper". You can use Dependency Walker program to get the function names (undecorated). Have a play around with the code and try other functions. The main thing is for string returns , memory needs to be allocated (for some scenarios) and has to return a DWORD pointer to the string. I used Resource Hacker to look up the resource strings table for each command.

+ Code Snippet
sync on : sync rate 30: sync

print "Loading Matrix1Util_16 dll..."
load dll "Matrix1Util_16.dll",1
if dll exist(1)=1
print "Calling DLL Function (FastUpper)...";
if dll call exist(1, "FastUpper")=1
print "okay."
//ptr as dword
//ptr = alloc(256)
ret as dword
ret = call dll (1,"FastUpper",0,"test")
print ret
t$=peek string(ret)
print t$
else
print "does not exist."
endif
print "Deleting DLL..."
delete dll 1
else
print "not loaded."
endif
sync
wait key
end


[recently added]

As in a previous post, here is how to return a string that uses the weird CreateDeleteString function used in the DBPRO globstruct.h.
Here, I've just added a dummy function with the ReverseString function. Which kind of defeats the object, but works as a quick workaround without having to do the whole pointer to globstruct stuff.
[recently added: meant to add that you can use any command from the dll to use in the dummy function and the dll needs to reside in the compiler plugin folder e,g, the user folder]

+ Code Snippet
sync on : sync rate 30: sync
print "TestCommands2 dll..."
load dll "TestCommands2.dll",1

if dll exist(1)=1
	print "Calling DLL Function (ReverseString)...";
	if dll call exist(1, "?ReverseString@@YAKKK@Z")=1
		print "okay."
		ptr as dword
		ptr = alloc(256)
		fill memory ptr,0,256
		poke string ptr,"Test"
		ret as dword
		ret = call dll (1,"?ReverseString@@YAKKK@Z",0,ptr)
		print ret
		t$=peek string(ret)
		print t$
	else
		print "does not exist."
	endif
	print "Deleting DLL..."
	delete dll 1
else
	print "not loaded."
endif
sync
wait key
end

function Dummy$()
	dum$=ReverseString$("dummy")
endfunction


Here's the whole of Matruxutils 14 functions being called (dummy function not required here):

+ Code Snippet
sync on : sync rate 30: sync
print "Loading Matrix1Util_14 dll..."
load dll "Matrix1Util_14.dll",1

if dll exist(1)=1
	print "Calling DLL Function (ProcessorCount)...";
	if dll call exist(1, "ProcessorCount")=1
		print "okay."
		ptr as dword
		ptr = call dll (1,"ProcessorCount")
		print ptr
		print "====================================="
	else
		print "does not exist."
	endif

	print "Calling DLL Function (ScancodeName)...";
	if dll call exist(1, "ScancodeName")=1
		print "okay."
		ptr as dword
		ptr = call dll (1,"ScancodeName",0,208)
		print ptr
		sc$=peek string(ptr)
		print sc$
		print "====================================="
	else
		print "does not exist."
	endif

	print "Calling DLL Function (UserName)...";
	if dll call exist(1, "UserName")=1
		print "okay."
		ptr as dword
		ptr = call dll (1,"UserName",0)
		print ptr
		user$=peek string(ptr)
		print user$
		print "====================================="
	else
		print "does not exist."
	endif

	print "Calling DLL Function (WindowsIs64Bit)...";
	if dll call exist(1, "WindowsIs64Bit")=1
		print "okay."
		ptr as dword
		ptr = call dll (1,"WindowsIs64Bit")
		print ptr
		print "====================================="
	else
		print "does not exist."
	endif

	print "Calling DLL Function (WindowsPlatform)...";
	if dll call exist(1, "WindowsPlatform")=1
		print "okay."
		ptr as dword
		ptr = call dll (1,"WindowsPlatform")
		print ptr
		print "====================================="
	else
		print "does not exist."
	endif

	print "Calling DLL Function (WindowsVersion)...";
	if dll call exist(1, "WindowsVersion")=1
		print "okay."
		ptr as dword
		ptr = call dll (1,"WindowsVersion")
		print ptr
		print "====================================="
	else
		print "does not exist."
	endif
	print "Deleting DLL..."
	delete dll 1
else
	print "not loaded."
endif
sync
wait key
end

Posted: 11th Feb 2019 14:37
Currently making updates to some C code to remove the need for the dummy function so DBPro doesn't crash.
Posted: 13th Feb 2019 19:14
DBPro program now updated as below, post C code update:
so what I did is remove (temporarily) all plugin-user dll's except IanM's Matrix1 #20 dll (to prevent any dll clashes e.g. functions with the same name). I then updated his Matrix1Utility C code to include the "Reverse String" function code but using Ian's Create, Delete and Emtpy string functions. Updated the .rc file using the decorated function name and then copied the compiled DLL to the plugin-user folder. Ran the code below which now no longer uses the dummy function and reverses the string without crashing. I'll update posts if I remember anything else. You must make sure that the "?ReceiveCoreDataPtr@@YAXPAX@Z" related lines are included or you get a crash. In addition, I no longer have any user dlls in the program app root folder just in the plugin-user folder. I'll be making further tests just to rule out anything I may have overlooked, but all seems to work well.


+ Code Snippet
Rem ***** Main Source File *****
sync on : sync rate 30 : sync

dllhandle = load dll ("Matrix1Utility.DLL")
dllhandleisvalid = dll handle is valid(dllhandle)

reccoreptr = get ptr to dll function ( dllhandle, "?ReceiveCoreDataPtr@@YAXPAX@Z")
reccoreptrisvalid = function ptr is valid(reccoreptr)

funcptr as dword
funcptr = get ptr to dll function ( dllhandle, "?PadLeft@@YAKPAD0K@Z")
funcptrisvalid = function ptr is valid(funcptr)

funcrevptr as dword
funcrevptr = get ptr to dll function ( dllhandle, "?RevString@@YAKPAD0@Z")
funcrevptrisvalid = function ptr is valid(funcrevptr)

print "dllhandle: ";dllhandle
print "dllhandleisvalid: ";dllhandleisvalid
print "reccoreptr: ";reccoreptr;" | ";*reccoreptr
print "reccoreptrisvalid: ";reccoreptrisvalid
print "funcptr: ";funcptr
print "funcptrisvalid: ";funcptrisvalid
print "funcrevptr: ";funcrevptr
print "funcrevptrisvalid: ";funcrevptrisvalid

s$="This is a test."
slen=len(s$)+1
padn=20
totlen = slen+padn
strptr as dword
strptr = make memory(totlen)
fill memory strptr,0,totlen
poke string strptr,s$
ret$ = call function ptr ( funcptr,0,strptr,totlen )
print ret$

revstring as dword
revstring = call function ptr (funcrevptr, 0,s$  )
print revstring
print peek string(revstring)

sync
wait key
end



C code added to Matrix1Utility program found here:
http://www.matrix1.demon.co.uk/

+ Code Snippet
EXPORT DWORD RevString(LPSTR OrigStr, LPSTR Source)
{
  DeleteString(OrigStr);

  if (! Source)
    return EmptyString();

	// Return string pointer
	LPSTR pReturnString=NULL;

	// If input string valid
	if(Source)
	{
		// Create a new string and copy input string to it
		DWORD dwSize=strlen( (LPSTR)Source );
		pReturnString=CreateString ( dwSize+1 );
		strcpy(pReturnString, (LPSTR)Source);

		// Reverse the new string
		strrev(pReturnString);
	}

  //return Cast( CreateString(Source) );
  return Cast( pReturnString );
}
Posted: 14th Feb 2019 6:34
if you want to obtain the Globstruct pointer, just add following code to your dll:

EXPORT DWORD GetGlobPtr(void)
{
return (DWORD)&Core;
}

and then add a string table to the resource file (.rc), for example:

IDS_STRING216 "GETGLOBPTR[%D%?GetGlobPtr@@YAKXZ"
copy the updated dll into the plugin-user folder again...

...and then in your db code just as a tester add:

globptr as dword
globptr = getglobptr()
print globptr
print *globptr

globptrstart=*globptr
print peek string(globptrstart+313)

all being well you should see a text string showing your appdata temp folder.