Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
call function that pass string from RapidQ
#1
Hi!

I try to call function in freeBAsic dll from RapidQ Basic.
AddNumbers example works good, but my function that pass string as parameter is not working:

FB dll code

Code:
'****************************'
declare function teststr     lib "mydll1" alias "teststr"     ( tstr as string ) as integer
[...] '

function teststr    ( tstr as string ) as integer  export
'print "tstr=" ;tstr
dim b as integer
b=5
teststr=b
end function

In RapidQ

Code:
declare function teststr lib "mydll1" alias "teststr@4" (  tstr as string ) as integer
print "teststr=" ;teststr ("aaaasddf")

If
print "tstr=" ;tstr
is commented in dll code all working good and function return 5.
If print "tstr=" ;tstr uncommented - error occures

Exception EAccessViolation in module MYDLL1.DLL at 0000161A.
Access violation at address 1000161A in module 'MYDLL1.DLL'. Read of address 61616161.

Another words when I don't accces to tstr var - all works good.

There are not problem, when I call it from FreeBasic. My function teststr works good.

2. Also as I see real name in dll is teststr@4, where 4 - parameters length (?). Why it's =4 when string is passed? Is passed pointer to string ?

3. Can I see example how to use cdecl in dll?

In export.bas example I have found

Code:
function AddNumbers cdecl alias "AddNumbers" ( byval operand1 as integer, byval operand2 as integer ) as integer export
--
But error occures, when I try to use it in dll code

Sorry for my English.
ith best regards, Andrew Shelkovenko.
http://www.wildgardenseed.com/RQDP/FreeBasic/index.html - FreeBasic documentation Project
Reply
#2
RapidQ and FreeBASIC probably use different formats for string descriptors. RapidQ might not even use string descriptors.
Reply
#3
Try declaring the string in RapidQ as ByVal - this should pass a pointer to the string data, just like a C string. I don't know if RapidQ supports passing as a C string, though - but VB does... RapidQ people, help! Wink
Reply
#4
Thanks for reply!

When I change code to

Code:
declare function teststr lib "mydll1" alias "teststr@4" (  tstr1 as long ) as integer

aa$="aaaasddf"
print "teststr=" ;teststr ( aa$)

there are no errors, but string value not passed and epty string
printed.

In other cases there are error:
teststr=tstr=Exception EAccessViolation in module MSVCRT.DLL at 000114BA.
Access violation at address 780114BA in module 'MSVCRT.DLL'. Read of address 61616161
ith best regards, Andrew Shelkovenko.
http://www.wildgardenseed.com/RQDP/FreeBasic/index.html - FreeBasic documentation Project
Reply
#5
Strings are different beasts in FB/VB/PB/RQ, as the descriptors are not the same.

I don't know RQ's default param passing, but try to declare it as BYVAL tstr1 AS LONG.

At FB side, you can't have BYVAL string's at the moment, so you must declare it as BYVAL tstr1 AS BYTE PTR, you can then copy it to a FB string as "somefbstr = *tstr1" or set it with another string as "*tstr1 = somefbstr", but be sure tstr1 is large enough, as its size is unknown by FB and can't be checked. You can't concatenate BYTE PTR's currently, and printing it directly will print just the first char, as PRINT will see it as a single byte, not as a stream of bytes.

When BYVAL string arguments get added, it will be easier, but sharing strings and arrays between different languages was never simple to be done..
Reply
#6
Afaik, a DLL only deal with a number or pointer. There is no direct string parsing. If you send a string argument from the calling program, you should give the string pointer address. Then the DLL will get the string from the memory location and manipulate it.

The question is, what keyword used in FB to transfer string from the given address to internal DLL string variable? Is it Varptr$() like one in Rapid-Q? Or there is Memcpy() api function exist to transfer string and it's size to internal string variable?

For an example of DLL funtion:

Code:
Declare Function DoString (lpzStr As String Ptr) Export As Long

Function DoString (lpzStr As String Ptr) Export As Long
    Dim iStr$ As String
         iStr$ = Varptr$(lpzStr)     ' Is this working in FB?

    Print iStr$ + " Size = "
    DoString = Len(iStr$)
End Function

From the calling program like Rapid-Q, it should be like this:

Code:
$AppType Console

Declare Function DoString Lib "TheDLL" Alias "DoString@4" (Byval lpzStr As Long) As Long

Defstr myString$ = "qwerty"

Print DoString(varptr(myString$))

Is Varptr$ is the correct use to get a string from a memory location in FB?
Reply
#7
In FB you can use sadd() (as in QB) or strptr() (as in PB) to get the pointer to the string data, varptr() or @ on a dynamic string will get the pointer to the string descriptor, as in QB/PB.
Reply
#8
sadd() and strptr() function only returning a pointer or numeric re-presentation of memory location. So to speak, the variable call this function must be a numeric variable, not a string variable.

So, what is the internal function that returning string content from given string address?
Reply
#9
They return the pointer to string's data, i dunno what you mean by "string contents".

Code:
dim p as byte ptr
  s$ = "abc"
  p = strptr( s$ )

  for i = 1 to len( s$ )
    print chr$(*p);
    p += 1
  next i
Reply
#10
I think I understand him. I'll attempt to translate to English:
He wants a function that returns a string pointer, one that can be dereferenced to a string rather than to a byte.

no.d: What you seem to have in mind cannot work, because different dialects of basic handle strings differently.

How do DLLs do it? They don't. They don't convert that pointer into a string. Instead they work with the bytes that pointer points to as an array of bytes. If the DLL is written in C, working with it as an array of bytes is how they would do it anyway, as C has no string type.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)