I'm going to write some procedures in an assembler.dll for a High Level Language (similar to VB) to speed up some API-Routines.

For Explanation of this problem:
The API-"sendmessage-function" - for example to fill the Items and Subitems of a listview-control in this language are working, but unfortunatelly this is very slow.

I've speeded up (ca. 70%) this by putting the sendmessage-function into an assembler.dll, more details see below... .

Now there is another problem, annoying me:
Most of the api-functions are expecting to pass a Pointer of a string, but doing this in the HLL means again to lose performance.

How can I pass a simple "Quoted String" to a procedure in the assembler.dll and get in the assembler-procedure the address of the given string to invoke an API-Call which is expecting a null-terminated string ???

To describe this problem:

assembler.dll is loaded (loadlibrary)

- the calling programm has a function and syntax like this:

insertnewTab :(handleofTabcontrol,mask,Tabcontrolnumber,"Textstring",Image)

and the corresponding procedure in the *.dll:

insert_new_mdi_tab proc tabhandle:DWORD, maske:DWORD, nummer:DWORD, ??? , image:DWORD

m2m TCI.imask,maske
m2m TCI.pszText,text ???-- Here is the question !!!
m2m TCI.iImage,image
invoke SendMessage,tabhandle,TCM_INSERTITEM,nummer,ADDR TCI
insert_new_mdi_tab Endp

How can I get the address/offset of the quoted string and how do I pass this to the Proc of the assembler.dll ???

At least, excuse me please, because I'm a newcomer. Up to this time I was working as an autodidact. But at this time I need help !!!

I would be very glad, if somebody can help me.
Posted on 2002-03-02 09:30:08 by mittern8

I don't know exactly but I think there is no need to create a pointer to a string when calling a function with VB.

Public Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long

This is the declaration of the API "MessageBox" for VB.
Usually MessageBox needs a pointer to the string which should be displayed. In VB you can call this function with strings as arguments:

MessageBox(hWnd, "Hello World", "ABC", 0)

So i think the compiler (or what ever Vb needs :grin: ) creates the pointer and stores the string somewhere in the memory..

Just try to call your DLL-function similar!
If it works, I am right :tongue:

Posted on 2002-03-02 11:55:59 by Rennsemmel

There are a few basics that you need to understand, the stack is not big enough to hold the actual character data so you always pass the address of the string. From memory if you pass the VB string by reference which is normal, the address of the string is what you get at the DLL end which will be a DWORD.

Now there are two things that may complicate this, the passed pointer MAY be an extra level of indirection that needs to be dereferenced for st to get the address, the second is to know if the address passed is to a BYTE sequence or to a UNICODE string. What I would suggest is that you write a small test piece interfacing VB with it and test out what turns up.


Posted on 2002-03-02 17:09:00 by hutch--
VB uses BSTR exclusively internally so you'll need to convert it to ASCIIz to work I think :/ (I don't think VB handles this for you)
Posted on 2002-03-02 17:39:27 by Hiroshimator

Many of us program in other languages beside assembler. I do program in VB like you do.

Sometimes we fail to get the most out of the "other" language, in order to justify an assembler solution. Only to find, that assembler requires us to be better programmers in the first place. Working backwards the lessons learned from assembler into the "other" language to improve our programming skills.

In assembler, we would not program in any refreshes until the data load task was complete, unless there was a reason to.

A common problem with VB is the Refreshes ( between the AddItem methods for your control. ) slowing down data loads for controls. Setting a control's redraw property to false during data loads speeds up the task at hand, and when done turn it back on.
'The example is for a TreeView, but works for most data bound controls.
180 SendMessage TreeView1.hWnd, WM_SETREDRAW, False, 0&
'Your Data loading code goes here.
2750 SendMessage TreeView1.hWnd, WM_SETREDRAW, True, 0&
2760 TreeView1.Refresh

Enjoy your work, P1
Posted on 2002-03-03 17:15:30 by Pone
VB uses BSTR exclusively internally so you'll need to convert it to ASCIIz to work I think

This is a reply to both hutch and Hiro,
VB will automatically convert the string from BSTR to ANSI for you, if you pass it ByVal. If you pass it ByRef, you will get a pointer to the BSTR.

You can just put text strings in your function call, like Rennsemmel pointed out. VB will then create the string in temporary space, and pass your function a pointer to it. Do not keep a copy of the pointer and try to use it after returning from that function, because VB destroys the string when you return from the called function. Unless you specifically want to deal with BSTRs (unlikely, unless you are doing COM stuff), then you always want to pass your strings ByVal. The ANSI string that VB creates for you in this case is also temporary, as is the pointer that your function is passed. If you need to keep a copy of the string, you will need to allocate a buffer and copy the temporary string to it.
Posted on 2002-03-03 19:48:24 by sluggy

Thanks for that bit of info, I knew there was a conversion done in VB but I don't keep it loaded on my box at all so I have no way of testing it.


Posted on 2002-03-03 20:25:06 by hutch--