How to use a dll created in Nim in FreeBasic ?

New to FreeBASIC? Post your questions here.
Post Reply
kcvinu
Posts: 232
Joined: Oct 07, 2015 16:44
Location: Keralam, India

How to use a dll created in Nim in FreeBasic ?

Post by kcvinu »

Hi,
Last week, i searched & tried a lot in freebasic to get the com object of a running excel file. But Disphelper library only gives a CreateObject function. It is not giving a GetObject function. At last, Jose Roca gave me a function to get an IDispatch ptr of the running excel object. But i failed to get the com object and related properties with that pointer. So i tried to find that feature in another language. Finally, i got a new language called Nim. Python like syntax and C like speed. Actually it compiles to C. So far so good. I have created a Nim dll to get the ActiveWindow caption of an excel file. Nim string is unicode. The One and only function in dll will return a Nim String.
How to use this dll in FreeBasic.
I have tried this but failed. Compiler says this ---- "cannot find -lDllTest.dll" I am sure that my dll's name is "DllTest", not "lDllTest".

Code: Select all

#Inclib "DllTest"
#Include Once "Afx/CWSTR.inc"
#Include "windows.bi"
Extern "C"
Declare Function GetExcelWinTitle Lib "DllTest.dll"() As String
End Extern
#Macro MsgBox(sMsg)
	MessageBoxW(0, Str(sMsg), "Message", MB_OK)
#Endmacro

Dim exCap As CWSTR=  GetExcelWinTitle()
MsgBox(exCap )

Sleep
And here is my Nim code

Code: Select all

import  winim/com 

proc GetExcelWinTitle*() : string {.stdcall, exportc:"GetExcelWinTitle", dynlib.} = 
    try :
        var exl = GetObject("", "Excel.Application")
        result = exl.ActiveWindow.Caption
    except : 
        echo "Excel is not opned"

srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: How to use a dll created in Nim in FreeBasic ?

Post by srvaldez »

Hi kcvinu
are you building for 32 or 64-bit?
kcvinu
Posts: 232
Joined: Oct 07, 2015 16:44
Location: Keralam, India

Re: How to use a dll created in Nim in FreeBasic ?

Post by kcvinu »

@srvaldez,
I would like to use both version, but mainly i am aiming at 32 bit version.
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: How to use a dll created in Nim in FreeBasic ?

Post by St_W »

libraries are specified using the "-l" option, so that "-l" just means "library". The library name musn not inlclude the ".dll" suffix. So the error message is correct:
"cannot find -lDllTest.dll" means:
"cannot find library DllTest.dll.dll"
kcvinu
Posts: 232
Joined: Oct 07, 2015 16:44
Location: Keralam, India

Re: How to use a dll created in Nim in FreeBasic ?

Post by kcvinu »

@st_W
Thanks a lot. It worked. But not as i expect. I think there is a data type problem. I can access a string pointer as return value from this function. But not the string. Need to experiment with both languages.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: How to use a dll created in Nim in FreeBasic ?

Post by Josep Roca »

kcvinu wrote:@st_W
Thanks a lot. It worked. But not as i expect. I think there is a data type problem. I can access a string pointer as return value from this function. But not the string. Need to experiment with both languages.
But a pointer to what? Certainly not a pointer to a FB string, so don't declare the return type "As String".
srvaldez
Posts: 3373
Joined: Sep 25, 2005 21:54

Re: How to use a dll created in Nim in FreeBasic ?

Post by srvaldez »

@kcvinu
just for fun, try

Code: Select all

Declare Function GetExcelWinTitle Lib "DllTest.dll"() As ZString ptr
' rest of code
'
Dim exCap As ZString ptr =  GetExcelWinTitle()
MsgBox(*exCap )
Sleep
I am not sure whether one should allocate memory for exCap or not, maybe like the following

Code: Select all

Declare Function GetExcelWinTitle Lib "DllTest.dll"() As ZString ptr
' rest of code
'
Dim exCap As ZString ptr =  allocate(256)
exCap = GetExcelWinTitle()
MsgBox(*exCap )
deallocate(exCap)
Sleep
@kcvinu, I downloaded NIM yesterday to see if it would help me to help you, but NIM complained that it could not find winim/com.
please tell me what's needed to setup NIM.

ps
Josep Roca is right, for starters, I would try to write the NIM dll so that it would write to a FreeBASIC string variable passed by reference to the dll, something like what sprintf does.
Last edited by srvaldez on Sep 18, 2018 22:19, edited 4 times in total.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: How to use a dll created in Nim in FreeBasic ?

Post by Josep Roca »

If they are unicode strings they aren't going to return a ZString Ptr. How to deal with it depends on what type of pointer it returns.

Also they wotk with UTF-16, UTF-8, a propietary format? The returned memory must be freed? It is essential to know how that language manages the memory for strings.
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: How to use a dll created in Nim in FreeBasic ?

Post by paul doe »

kcvinu wrote:Thanks a lot. It worked. But not as i expect. I think there is a data type problem. I can access a string pointer as return value from this function. But not the string. Need to experiment with both languages.
Does NIM allows you to allocate a raw stream of bytes? In that case, you can simply pass the string as a raw byte stream, along with the length, and reinterpret cast it from FreeBasic (not a functional DLL, just some code to give you the idea):

Code: Select all

  /'
    This would be the function in the NIM DLL
    
    If the two languages aren't ABI compatible, your best bet would be to
    simply pass raw stream of bytes between them, and the reinterpret them
    from each side as needed.
  '/
function NIMFunction( byref bytes as ulong ) as any ptr
  '' Create a string in NIM
  dim as string s = "This is a test"
  
  '' Allocate some raw bytes and store the string data there
  dim as ubyte ptr ret = new ubyte[ len( s ) ]
  '' And fill the buffer appropriately
  *cptr( string ptr, ret ) = *strPtr( s )
  
  '' Return the byte stream and the length of it to the calling app
  bytes = len( s )
  return( ret )
end function

/'
  And this is the code required from the FreeBasic side
'/
dim as ulong strLen
dim as ubyte ptr s = NIMFunction( strLen )

'' Allocate the string
dim as string st = space( strLen )

'' Reinterpret the cast from here
st = *cptr( string ptr, s )

? st

'' Don't forget to delete the stream of bytes when finished
delete[]( s )

sleep()
This is FB's internal string representation, if you want to interface them with NIM:

Code: Select all

/'
	FreeBasic internal string representation
'/
type FBString
  charData  as ubyte ptr
  length    as integer
  size      as integer
end type
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: How to use a dll created in Nim in FreeBasic ?

Post by caseih »

To get unicode from Nim to FreeBASIC, you'll have to have Nim *encode* the unicode string to a particular byte format. If it's on Windows, you can encode to UTF-16 bytes, which you can then say is a WString ptr. If it's on Linux, you'll need to encode to UTF-8, and which will be a standard zstring ptr in FB.

Furthermore, anything you pass to Nim functions will need to be decoded from whatever encoding you're using in FB (UTF-16 if you're dealing with WStrings).
kcvinu
Posts: 232
Joined: Oct 07, 2015 16:44
Location: Keralam, India

Re: How to use a dll created in Nim in FreeBasic ?

Post by kcvinu »

srvaldez wrote: @kcvinu, I downloaded NIM yesterday to see if it would help me to help you, but NIM complained that it could not find winim/com.
please tell me what's needed to setup NIM.
Hi, sorry for the delay. I was little busy with my works. Thanks for the reply. If you installed nim, then most probably you have installed nim's package manager "nimble". If so, you can download "winim" from Github. After downloading the source, from that directory, run your cmd and write "nimble install". Thats all. BTW, nim is actually fun.
kcvinu
Posts: 232
Joined: Oct 07, 2015 16:44
Location: Keralam, India

Re: How to use a dll created in Nim in FreeBasic ?

Post by kcvinu »

paul doe wrote: Does NIM allows you to allocate a raw stream of bytes?
Yes. In Nim, two types of pointers are there. One is "ref" pointer, which is traced aka garbage collected pointer. Other one is "ptr" pointer, which is an untraced pointer.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How to use a dll created in Nim in FreeBasic ?

Post by dodicat »

You could try loadlibraryex.
Parameter 3 can be tweaked in value.
start 0 then 1 ...
(Google to see the list of parameters)
Example:

Code: Select all

 
screen 20

declare function LoadLibraryExA alias "LoadLibraryExA"(byval as zstring ptr, byval as any ptr,byval as long) as any ptr


dim as any ptr L=LoadLibraryexA("UxTheme.dll ",0,0)
if L=0 then print "unable to load dll":sleep:end 

dim Theme as function(As Any Ptr,As zstring ptr =@"",As zstring ptr =@"") As Long = dylibsymbol(L,"SetWindowTheme")
if Theme=0 then print "unable to load function":sleep:end 


Dim Win As Any Ptr
Screencontrol 2,*Cptr(Integer Ptr,@Win )
Theme(win)
print L
print Theme

sleep  
Post Reply