dll strings?
dll strings?
Hi,
in converting egrid to a dll in order to target other development languages, I have a couple of exported functions which either take strings as parameters or return strings.
I was wondering as to the best way of doing this, bearing in mind that the dll could (fingers crossed!) be used in other languages?
Should I use and insist upon pointers to null-terminated strings and memory buffers etc?
Or can certain other languages just pass a string in the same way that PB does and in the correct format?
Afraid I have little experience (well no experience actually!) of such things and I don't know enough about how other languages handle strings.
Thanks in advance for any advice.
in converting egrid to a dll in order to target other development languages, I have a couple of exported functions which either take strings as parameters or return strings.
I was wondering as to the best way of doing this, bearing in mind that the dll could (fingers crossed!) be used in other languages?
Should I use and insist upon pointers to null-terminated strings and memory buffers etc?
Or can certain other languages just pass a string in the same way that PB does and in the correct format?
Afraid I have little experience (well no experience actually!) of such things and I don't know enough about how other languages handle strings.
Thanks in advance for any advice.
I may look like a mule, but I'm not a complete ass.
Thanks.
But what I'm not sure about is that if I have an exported procedure such as:
How will another programming language pass it's string? Will it even work or do I have to rewrite the above to explicitly use pointers:
and demand that any code calling the above procedure does so by explicitly passing the address of the string parameter?
I know that Purebasic does this anyhow, but I'm not thinking about Purebasic at the moment.
But what I'm not sure about is that if I have an exported procedure such as:
Code: Select all
ProcedureDLL Test(string.s)
etc.
Code: Select all
ProcedureDLL Test(*string)
etc.
I know that Purebasic does this anyhow, but I'm not thinking about Purebasic at the moment.
I may look like a mule, but I'm not a complete ass.
Interesting - sounds good.
I have one exported function which returns a string. I've read what the manual says regarding making the string global, and the fact that a pointer is returned but am still undecided whether to move towards the use of memory buffers.
Thanks again.
I have one exported function which returns a string. I've read what the manual says regarding making the string global, and the fact that a pointer is returned but am still undecided whether to move towards the use of memory buffers.
Thanks again.
I may look like a mule, but I'm not a complete ass.
-
Edwin Knoppert
- Addict

- Posts: 1073
- Joined: Fri Apr 25, 2003 11:13 pm
- Location: Netherlands
- Contact:
I don't think PB natively uses BSTR, after all are these not unicode only?Edwin Knoppert wrote:A recurring remark of me.. BSTR
So look me up
SysAlloc...() and such.
Afaik the new pb has a different engine and might be BSTR based??
Besides, my lib would perhaps get away with treating these as null-terminated c-style strings anyhow. There's not much chance that any code using my egrid lib will use a BSTR with a zero byte embedded (it's possible, but not that likely!) Returning such a string would pose more of a problem.
Besides (again!) those languages which natively use BSTR's (VB and the like) will have no need for egrid anyhow.
I may look like a mule, but I'm not a complete ass.
-
Edwin Knoppert
- Addict

- Posts: 1073
- Joined: Fri Apr 25, 2003 11:13 pm
- Location: Netherlands
- Contact:
Depends on the call, ansi and unicode strings can be created.
If it where native to pb by now it would be very nice.
To bad then..
If(so)
{
Might be a lack of understanding, and somehow i'm sorry my remarks where not explored, not that i'm such a genius but imo it would be the best choice.
It would not have hurt any current PB user.
}
BSTR is always null-terminated, the nul is the byte length + 1.
So passing the BSTR's memory address to a expected null-terminated function parameter would work 100%
A BSTR's handle is the start of the memory, the 4 bytes before the address contains the length.
So if you claimed 100 bytes, you'll get at least 105 bytes.
If it where native to pb by now it would be very nice.
To bad then..
If(so)
{
Might be a lack of understanding, and somehow i'm sorry my remarks where not explored, not that i'm such a genius but imo it would be the best choice.
It would not have hurt any current PB user.
}
BSTR is always null-terminated, the nul is the byte length + 1.
So passing the BSTR's memory address to a expected null-terminated function parameter would work 100%
A BSTR's handle is the start of the memory, the 4 bytes before the address contains the length.
So if you claimed 100 bytes, you'll get at least 105 bytes.
Yes, but returning such a string to the calling program would be fiddly as it would require SysAlloc etc.
All round, I'm leaning towards using memory buffers with null terminated C-style strings. No different to the way SQLite (for example) operates.
All round, I'm leaning towards using memory buffers with null terminated C-style strings. No different to the way SQLite (for example) operates.
I may look like a mule, but I'm not a complete ass.
-
Edwin Knoppert
- Addict

- Posts: 1073
- Joined: Fri Apr 25, 2003 11:13 pm
- Location: Netherlands
- Contact:
Of course it would, but there is no substitute for returning strings.srod wrote:Yes, but returning such a string to the calling program would be fiddly as it would require SysAlloc etc.
All round, I'm leaning towards using memory buffers with null terminated C-style strings. No different to the way SQLite (for example) operates.
C-billies often use cha pointers and static memory variables.
Afaik always not able to hold chr(0) as data.
A BSTR would make easy dll's for VB and similar, the programming languages not able to coop with BSTR (as return value from a dll) could use a simple wrapper.
I'm talking from experiance.
Enough said about this though.
-
Edwin Knoppert
- Addict

- Posts: 1073
- Joined: Fri Apr 25, 2003 11:13 pm
- Location: Netherlands
- Contact:
-
Edwin Knoppert
- Addict

- Posts: 1073
- Joined: Fri Apr 25, 2003 11:13 pm
- Location: Netherlands
- Contact:
Let me elaborate about bstr's used as return vartype.
If an exe (actually any calling pocedure) calls a dll which returns a bstr it's required the calling app destroys the BSTR handle.
Of course the calling app must declare the dll function: As String, where an application's String means a BSTR.
The dll has it's exported function prepared to return a BSTR.
In fact this is nothing more than returning the BSTR handle.
I have said before, a BSTR handle is the first byte in it's memory allocated.
Internally Windows knows this is a BSTR handle (if that is important at all).
The calling app receives the BSTR handle and translates that to a local string (copy) and frees the handle.
I'm not sure how this works with other vartypes like a long integer.
These might be stack stuff and eliminated in another way, don't know.
A few years back i have tested BSTR using handles and seen that if i didn't destroy the handle and did a new request a new allocation was made while if i freed it first the same address was reused.
A language as VB and PowerBASIC handle ANSI BSTR's this way fine.
VB's strings being passed as parameter BYVAL is an unicode string being translated to ansicode to accomadate programmers at that time.
The Windows api declarations where all ANSI.
If a string is passed byref than only it's handle/pointer is passed, no translation is done.
A sideeffect is that the function must know that it's a unicode string (BSTR is not really that important unless it need's to know it's length).
Since i'm doing asp.net i was looking for ways to use existing code placed in dll's for my dotnet stuff.
That's certainly not trivial stuff at all!!
A common mistake is to assume dotnet understands your bstr since you have declared the functions AS STRING.. wrong!
Again, the BSTR handle is also the first byte to your memory, the dotnet app sees the bytes until the first chr(0) (which is alwasy added internally) and voila, it seems to work.
Since i know from experiance it does not like the chr(0) in strings this way i assumed that is' not BSTR aware and choose to declare it as INT32 and used ordinary win32 SysAlloc... SysFree..() stuff and copied the data to local dotnet string.
Since this was a ansi BSTR, i also had to convert the bytes to unicode.
Good luck
If an exe (actually any calling pocedure) calls a dll which returns a bstr it's required the calling app destroys the BSTR handle.
Of course the calling app must declare the dll function: As String, where an application's String means a BSTR.
The dll has it's exported function prepared to return a BSTR.
In fact this is nothing more than returning the BSTR handle.
I have said before, a BSTR handle is the first byte in it's memory allocated.
Internally Windows knows this is a BSTR handle (if that is important at all).
The calling app receives the BSTR handle and translates that to a local string (copy) and frees the handle.
I'm not sure how this works with other vartypes like a long integer.
These might be stack stuff and eliminated in another way, don't know.
A few years back i have tested BSTR using handles and seen that if i didn't destroy the handle and did a new request a new allocation was made while if i freed it first the same address was reused.
A language as VB and PowerBASIC handle ANSI BSTR's this way fine.
VB's strings being passed as parameter BYVAL is an unicode string being translated to ansicode to accomadate programmers at that time.
The Windows api declarations where all ANSI.
If a string is passed byref than only it's handle/pointer is passed, no translation is done.
A sideeffect is that the function must know that it's a unicode string (BSTR is not really that important unless it need's to know it's length).
Since i'm doing asp.net i was looking for ways to use existing code placed in dll's for my dotnet stuff.
That's certainly not trivial stuff at all!!
A common mistake is to assume dotnet understands your bstr since you have declared the functions AS STRING.. wrong!
Again, the BSTR handle is also the first byte to your memory, the dotnet app sees the bytes until the first chr(0) (which is alwasy added internally) and voila, it seems to work.
Since i know from experiance it does not like the chr(0) in strings this way i assumed that is' not BSTR aware and choose to declare it as INT32 and used ordinary win32 SysAlloc... SysFree..() stuff and copied the data to local dotnet string.
Since this was a ansi BSTR, i also had to convert the bytes to unicode.
Good luck

