passing pointer

Monkey Forums/Monkey Programming/passing pointer

Emil_halim(Posted 2014) [#1]
Hi all

i have this c++ function
void* __stdcall Resource_Load(const char *filename, DWORD *size);


and i am using it in c++ like that
 DWORD size;
 void* p = Resource_Load(filename,&size);


so how can i declare it in monkey language?
please need monkey code example demonstrates using it.


Gerry Quinn(Posted 2014) [#2]
Assuming the resource you're loading isn't a standard Monkey object, I think you need to make a C++ class to hold it, inheriting from Object. Then the code above can be placed in a function or method of that class, which you can call as an Extern function or method from Monkey.


ImmutableOctet(SKNG)(Posted 2014) [#3]
Sorry, double post.


ImmutableOctet(SKNG)(Posted 2014) [#4]
Well, I've made various attempts to wrap C and C++ code within Monkey, but it usually becomes a chore without generics/templates, which Monkey doesn't support when dealing with external code. In the end, there's especially no clean way to wrap types from C++ in Monkey, however, that doesn't mean it isn't possible.

I've made various attempts involving containers of return values, and using the preprocessor with some weird techniques, and other hacks like that, but for an exact representation (Of pointers at least), you could use something like:

C++ code:
#define REMOVE_PARENTHESES(X) X


Monkey code:


Monkey always deals with objects and external types as pointers, so you need to keep that in mind. For example, if you have ' Class Short="short" ', it won't let you use it as a 'short', only a short-pointer (Without something like the hacks I mentioned above). The method I posted above should basically work, it's just not the best of options.

I know from experience that this is annoying, I tried wrapping the Windows API with Monkey, and it was a pain. I only got a hand-full of the commands and types done before realizing how ridiculous it was maintaining it. On the bright side, it worked amazingly well, but I just couldn't go on writing a mess like that. I may eventually just write a program to generate this kind of thing for me, but for now, this works.

EDIT: Just for the record, you'd still need to make your own system for generating a 'DWORD' container or other such method. Or hack together something in Monkey. I've been confusing the hell out of myself just writing this post, so that should tell you what you'd be getting into with this method. This also tends to make the debugger freak out a lot.


If you really want to go through the hassle, you can make it pretty much as nice as this:


The best option is usually a wrapper function or class written in C++, then brought into Monkey via 'Extern'.


Emil_halim(Posted 2014) [#5]
thanks ImmutableOcte,

actually your work around is amazing ,and worked well.

why Mark did not make any friendly solution , instead of work around.

here is a test program
Import zip 

Function Main:Int()
    
    Pack("README.TXT")
    
    Local txt:VoidPtr
    Local size:int
    txt = UnPack("README.dat",ADDROF(size))
    ! printf("%s\n",t_txt);
    ! free( t_txt );
    Return 0
End




Gerry Quinn(Posted 2014) [#6]
I think the issue is that the structure of Monkey is close to that of languages like Java, in which objects are distinct from primitives and always accessed by way of pointers. With C++ a memory address can contain anything. So Monkey translates to a version of C++ in which everything is referenced by pointers, but this doesn't fit well with native code written in a 'closer to the metal' idiom. Anyway, that's my guess,


ImmutableOctet(SKNG)(Posted 2014) [#7]
C and C++ are pretty much as close as you can get without ripping your hair out with assembly (Although, most assembly languages aren't all that bad), so that doesn't really make sense. The only big difference between Monkey X's generated code, and native C++ code is that objects written in Monkey X are deleted by a garbage collector, and we can't use 8-bit and 16-bit registers (And their respective data-types) without hacking them in. (And the generated code is horribly messy and compiled as one object) That, and Monkey doesn't tend to use the STL, but that's more of a standardization thing, than a language thing. In fact, I actually have gotten std::string to work perfectly in Monkey X. Using pointers tends to be a more hardware specific task (Albeit somewhat agnostic in C++), as you're purely dealing with memory (At least from the eyes of the client application). Monkey X's approach currently seems to be to only stack-allocate what it sees fit, and to allocate everything else on the heap, and manage it itself. This is something I don't really like about Monkey. Why can't I at the very least 'extern-in' something that uses the stack, and not have to worry about containers or hacks? Because return values tend to be handled by registers, C++ doesn't allow you to use the '&' operator on functions; this means the only way to use Monkey to get the value is to hack something together when the return-type isn't already a pointer.

At the end of the day, my hack works well enough, but it's a pain to work around, and it's honestly only efficient when dealing with pointers. That being said, the interface at least looks nice, even if it takes a while to get it that nice.