Is it possible with masm to create code, that can be used with C-language, like Structs with methods, constructors and deconstructors?
like

struct S
{
int a;
S(){};
~s(){};
};

Or...not possible??
Posted on 2003-04-14 11:54:11 by david
humm... I'd say it's not worth it. Rather build C++ classes (or C++ structs-with functions), and call external assembly code from the methods; if the CALL+RET overhead is too large, your program design is wrong.

If you really want to try, do a C++ class. Declare all methods as virtual. In masm, make a struct. The first entry is a DWORD that points to a table, the following are the class data members. The table is a "vtable", an array of pointers to functions (methods). This may or may not work, depending on how your compiler works, and is a pretty dirty way of doing stuff.
Posted on 2003-04-14 12:06:38 by f0dder
thanks.
I had the idea somehow everything in C was compatible with asm 0:-).
The c++ thing with tables sounds a little difficult and cumbersome, I do know how I can make the c++ compiler use masm compiling masm code, but I don't how I would make compiler (MSVC6.0) overload the c++ functions with the masm code...but I'll make a brave try tomorrow.

For the alternative with just making a c++ class and calling functions in a masm object file linked to the project for instance, would it be possible in the header for the masm file to declare all it's functions inline? Thus the code would not be called at all, but be inside the classes member functions no?
Posted on 2003-04-14 12:49:43 by david
Well. Non-virtual methods actually don't store anything special in the classes/structs (the "objects") - they are just functions with (very ;-)) special names (at link-time), that have access to the private data members. So you could do a struct and generate an asm listing, but again... it's not really worth it.


For the alternative with just making a c++ class and calling functions in a masm object file linked to the project for instance, would it be possible in the header for the masm file to declare all it's functions inline? Thus the code would not be called at all, but be inside the classes member functions no?

Nope. Such cross-module inlining is (generally) not possible. WIth vs.net and ICC7, however, some form of it is possible - by deferring pcode->native generation and optimization until link-time. That still can't inline native machine code objects though, only pcode.

Either use inline assembly, or do fully external asm. Don't do assembly for insignificant small pieces of code, and only use it where it matters. Inline vs. external is mostly a matter of taste and whether you need macros and such. Inline assembly is a nice way to play around with stuff, but I tend to shell out to external assembly (that way also reducing compiler dependancy - nasm can be used for gcc, vs.net, intel, and both under win32 and linux).

And again: if call+ret overhead to call external assembly within a class method is too much, you're not designing properly.
Posted on 2003-04-14 12:58:01 by f0dder
I hate inline asm. :grin:

hmm...ok I see, I just thought that some .lib with asm would be more easily maintained or attractive for a c/c++ programmer if it could be constructed as a class or struct invokabale from c/c++. Pity it seems hard like you say.

Are the object oriented methods developed by people at this forum invokable from c++ just like a normal class made with c++?
Posted on 2003-04-14 13:06:04 by david
I don't really fancy it either, and it might hinder some compilers optimizers. Better to only use asm where it really matters, and then shell it out to an external .asm file.
Posted on 2003-04-14 13:08:38 by f0dder

hmm...ok I see, I just thought that some .lib with asm would be more easily maintained or attractive for a c/c++ programmer if it could be constructed as a class or struct invokabale from c/c++. Pity it seems hard like you say.

Not in my line of thinking, really. As I see it, assembly is best employed to do some rather specialized function; usually it wouldn't make too much sense to put this stuff in a class, since there wouldn't be much stuff to group it with (while some people might enjoy the "everything in asm" programming approach, I don't). Thus, for me, it makes more sense to wrap a "regular" external function in a C++ member function. Only real con about this is you can't access member data.


Are the object oriented methods developed by people at this forum invokable from c++ just like a normal class made with c++?

Hrm. I think at least one of the projects is compatible with the COM object model, which can be used from C++.
Posted on 2003-04-14 15:54:05 by f0dder
Humm.. :( I tried make a struct with function to call from c++, it compiles (msvc++) but the linker doesnt understand where the Struct is inside the asm obj file or something:


Main.obj : error LNK2001: unresolved external symbol "public: void __thiscall Testar::Func(void)" (?Func@Testar@@QAEXXZ)


How can I make it work? :eek:




; asm file

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

.data


Testar STRUCT
testVar DWORD ?
Func DWORD offset HelloWorld
Testar ENDS

.code

HelloWorld PROC
invoke MessageBox, 0, 0, 0, MB_OK
ret
HelloWorld ENDP

END



c++ file




extern "C" struct Testar
{
long testVar;
void Func();
};

int main()
{
Testar T;
T.Func();


return 0;
}

Posted on 2003-04-20 16:13:21 by david
It's because of name mangling... just give up ;)
Posted on 2003-04-20 16:38:40 by f0dder
- class/struct methods do not exist in C, only in C++.
- The name decoration and calling convention of C functions are well defined and shared by most compilers. There are no such conventions for C++ (to allow each compiler to implement classes the way it likes). So C is pretty compatible with asm but C++ isn't.
- Non-virtual methods are just normal function calls (in VC at least, but compilers are free to do it differently), with a 'this' parameter passed somehow (VC usually uses ecx to do this)
- FYI (if you didn't know already): 'struct' = 'class' with public as the default access modifier. A structure isn't more 'low level' than a class just because struct was already available in C.

In your example, you would probably have to do something like this:
mov ecx, offset testStruct

call ?Func@Testar@@QAEXXZ


However I strongly recommend you to take f0dder's advice and stick with C functions. You could define a C function for every method and write a C++ wrapper class for it (GDI+ does that to be a C++ library while the underlying API actually consists of C functions).

Thomas
Posted on 2003-04-20 17:05:46 by Thomas
That was the "long answer" :-)

Btw, iirc there are a few differences between structs and classes, but... I might be wrong.
Posted on 2003-04-21 01:54:19 by f0dder
Hi Thomas,

you mentioned VC uses ecx as "this" pointer for non-virtual methods. I think thats true for private methods only. For public methods such a behaviour would be very strange. Havent tested this yet, though.

Japheth


I've tested it and you're right, Thomas. Even if I export public functions and put the class in a DLL the this pointer remains ECX. Dont think thats a good concept.
Posted on 2003-04-21 03:08:40 by japheth
Haah , I give up already.. :grin:


- Non-virtual methods are just normal function calls (in VC at least, but compilers are free to do it differently), with a 'this' parameter passed somehow (VC usually uses ecx to do this)


That's interesting. How's it working with a virtual function, there's some table of virtual pointers? How's this working?
( I know how to use virtual conecpt in c++, but I don't know how it's implemented lowlevel, I mean in the asm-code that's built )

and..


you mentioned VC uses ecx as "this" pointer for non-virtual methods. I think thats true for private methods only. For public methods such a behaviour would be very strange. Havent tested this yet, though.


Why would the use of a specific register be strange in this context? *curious*

:)
Posted on 2003-04-21 13:20:34 by david
Originally posted by david
That's interesting. How's it working with a virtual function, there's some table of virtual pointers? How's this working?
( I know how to use virtual conecpt in c++, but I don't know how it's implemented lowlevel, I mean in the asm-code that's built )

The first dword is a pointer to the virtual function table, which consists simply of function pointers. IIRC this function list is hardcoded in the program and referred to so the class instances do not have to include a full function table each time.

Why would the use of a specific register be strange in this context? *curious*

I would like to know that as well :). AFAIK, ecx is always used as a this pointer in any class function that isn't static (or inline).

Thomas
Posted on 2003-04-21 13:29:59 by Thomas
Hooray for _thiscall.
Posted on 2003-04-21 14:08:50 by iblis