News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

passing a string array from c++ into a masm function that will be called by c++

Started by bobl, April 27, 2013, 10:51:15 PM

Previous topic - Next topic

Gunther

Hi qWord,

Quote from: qWord on April 28, 2013, 04:23:01 AM
you might try to adapt the following lines:

I've my doubts that this will work. The assembly language function isn't with extern "C" a class member (see reply #11 of this thread). One could try the access with a friend function, but that's not easy.

Gunther
You have to know the facts before you can distort them.

qWord

Quote from: Gunther on April 28, 2013, 04:39:16 AMI've my doubts that this will work. The assembly language function isn't with extern "C" a class member (see reply #11 of this thread). One could try the access with a friend function, but that's not easy.
it should work (at least) as long as he does not put the function in any namespace/class.
MREAL macros - when you need floating point arithmetic while assembling!

Gunther

Hi qWord,

Here is a quote from bobl's first post:
Quote
Re the strings. At present they're in a TStringList...which is a class.

That's the tricky point.

Gunther
You have to know the facts before you can distort them.

qWord

Quote from: Gunther on April 28, 2013, 06:17:54 AM
Quote
Re the strings. At present they're in a TStringList...which is a class.

That's the tricky point.
you are thinking to complicated: he can declare the function outside the class (=>global scope in corresponding module) and then call it inside a wrapper method (of class XYZ).
MREAL macros - when you need floating point arithmetic while assembling!

Gunther

Hi qWord,

Quote from: qWord on April 28, 2013, 06:29:31 AM
you are thinking to complicated: he can declare the function outside the class (=>global scope in corresponding module) and then call it inside a wrapper method (of class XYZ).

did you ever try that?

Gunther
You have to know the facts before you can distort them.

jj2007

I guess passing an array from C++ to Assembler is not a big deal - Olly will reveal how to do that ;-)

In the meantime, I've tested the opposite direction: Let Masm create and handle the string array. Below are the assembler and C++ sources. In VC++ 2010 Express, it works if a) VC and Masm32 are on the same drive and b) after assembling, you drag the RecallArray.obj (attached below) over the bold Recall in VC's solution explorer window.

Assembler, RecallArray.asm:
Quoteinclude \masm32\MasmBasic\MasmBasic.inc        ; Pure MasmTM

.data?
ctStrings        dd ?

.code
AsmLoadArray proc C filename        ; loads textfile to string array
  Recall filename, My$()
  mov ctStrings, eax
  ret                        ; returns #strings loaded
AsmLoadArray endp

Asm$ proc C inx        ; returns Asm$(index)
  mov eax, My$(inx)        ; returns ptr to string
  ret
Asm$ endp

SetAsm$ proc C inx, newtext        ; assigns new string to array element
  Let My$(inx)=newtext        ; no return value
  ret
SetAsm$ endp

end
C++, Recall.cpp:
Quote#include <stdio.h>

extern "C" int AsmLoadArray(char* filename);
extern "C" char* Asm$(int index);
extern "C" int SetAsm$(int index, char* newtext);

int main () {
       
int i, NumStrings=AsmLoadArray("C:\\Masm32\\Examples\\exampl01\\generic\\generic.asm");
       
printf("%i strings loaded\n", NumStrings);

       
SetAsm$(NumStrings-2, "\tWe played a little trick");
       
SetAsm$(NumStrings-1, Asm$(NumStrings-3));

       
for (i=0;i<20;i++){
               
printf("%i\t%s\n", i, Asm$(i));
       
}

       
printf("%s\n", "...");

       
for (i=NumStrings-20;i<NumStrings;i++){
               
printf("%i\t%s\n", i, Asm$(i));
       
}

       
void getc();
       
return 0;
}

The code itself is trivial. I spent half an evening, however, to convince VC that printing to a console window is an important activity (and was honoured by endless error messages), and the other half to find out that VC and Masm32 have to be on the same drive. Now I am collecting a long list of words that start with C, like crap, creeps, clumsy etc, in order to push my blood pressure down to normal :bgrin:

P.S. - Just one example why I consider VC a sh***y product:
- press in VC Ctrl F5 to build the Recall project (should work if the obj & lib from the archive are there)
- Rename MasmBasic.lib to whatever.lib
- press in VC F5:
1. You will see for some microseconds the usual output (why does that bloody M$ product not recognise that a console window must stay open??? especially since there is a getc...), proof that the exe works
2. Endless complaints à la 'Recall.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', Cannot find or open the PDB file
3. At the end, "The program '[3028] Recall.exe: Native' has exited with code 0 (0x0)."
Great, it worked :t

- now press in VC F7: === Build: 0 succeeded, 0 failed, 1 up-to-date, 0 skipped ===
Great, it worked :t

- now press in VC Ctrl F7:
------ Build started: Project: Recall, Configuration: Debug Win32 ------
  Skipping... (no relevant changes detected)
  Recall.cpp
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Great, it worked :t

- now press in VC Ctrl F5:
------ Build started: Project: Recall, Configuration: Debug Win32 ------
LINK : fatal error LNK1104: cannot open file '\masm32\MasmBasic\MasmBasic.lib'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

IMHO Bill Gates should be thrown in jail 8)

qWord

Quote from: Gunther on April 28, 2013, 09:25:13 AMdid you ever try that?
yes.
the following example works with VS2010 and g++ 4.6.2.
#include <iostream>
#include <list>

extern "C" bool __cdecl fn1(const char** p,int n);

class foo
{
    std::list<std::string*> tkns;
public:
    foo() {
        tkns.push_back(new std::string("foo1"));
        tkns.push_back(new std::string("foo2"));
        tkns.push_back(new std::string("foo3"));
    }

    ~foo() {
        for(std::list<std::string*>::iterator itr = tkns.begin(); itr!=tkns.end();itr++)
            delete *itr;
    }

    bool callMASM() {
        try {
            const char** ppsz = new const char*[tkns.size()];
            int i=0;
            for(std::list<std::string*>::iterator itr = tkns.begin(); itr!=tkns.end();itr++)
                ppsz[i++] = (*itr)->c_str();

            bool ret = fn1(ppsz,tkns.size());
            delete [] ppsz;
            return ret;
        }
        catch (...) {std::cout << "error\n"; return false;}
    }
};

int main() {
    foo x;

    x.callMASM();

    return 0;
}

include \masm32\include\masm32rt.inc
.code

fn1 proc C uses esi edi p:ptr PCHAR,n:DWORD

xor esi,esi
mov edi,p
.while esi < n
print PCHAR ptr [edi+esi*PCHAR],13,10
inc esi
.endw
mov eax,TRUE
ret

fn1 endp
end
MREAL macros - when you need floating point arithmetic while assembling!

bobl

I'm very grateful to you all for your experiments and persistence.
It helps a lot!
I'll post what I've done when I'm happy with it.
Thank you all very much indeed.

Gunther

Hi bobl,

Quote from: bobl on April 28, 2013, 11:18:42 PM
I'm very grateful to you all for your experiments and persistence.
It helps a lot!
I'll post what I've done when I'm happy with it.
Thank you all very much indeed.

that's what friends are for.  :icon_cool:

Gunther
You have to know the facts before you can distort them.

bobl

That's very kind of you Gunther. Thank you.
I said I'd come back when I got something I was happy with.
I  lied.
I've been trying to apply QWORD'S assembler function to TStringLists as simply as possible to start with...

//---------------------------------------------------------------------------

#include <vcl.h>
#include <iostream.h>
using namespace std;

#pragma hdrstop

//---------------------------------------------------------------------------

extern "C" bool __cdecl fn1(const char** p,int n);

#pragma argsused
int main(int argc, char* argv[])
{
int i,j;
TStringList * tkns = new TStringList;
tkns->Add("aaa");
tkns->Add("bbb");
tkns->Add("ccc");
char ** pp;
const char ** cpp;
char * p[3];
p[0] = tkns->Strings[0].c_str();
p[1] = tkns->Strings[1].c_str();
p[2] = tkns->Strings[2].c_str();
pp = p;
cpp = (const char **)pp;
//test =========================
cout << cpp[0] << "\n"; //tick
cout << cpp[1] << "\n"; //tick
cout << cpp[2] << "\n"; //tick
//end test =====================
fn1(cpp,2);
cin >> j;
delete tkns;
return 0;
}

Unfortunately...including the line...fn1(cpp,2);... is giving me the message...

[Linker Error] Error: Unresolved external '_StdOut@4' referenced from C:\MY_DELPHI\MY_CBUILDER2006\PROJ4\MYOMFDMASM.OBJ

Any ideas anyone?
I'm just wondering if there's something intrinsically wrong with my C++?


qWord

Quote from: bobl on April 29, 2013, 01:48:30 AMUnfortunately...including the line fn1() is giving me the message...

[Linker Error] Error: Unresolved external '_StdOut@4' referenced from C:\MY_DELPHI\MY_CBUILDER2006\PROJ4\MYOMFDMASM.OBJ

Any ideas?
add the library \masm32\lib\masm32.lib
MREAL macros - when you need floating point arithmetic while assembling!

bobl

Thanks for the advice
Because it didn't satisfy BCB2006's OMF requirements I copied masm32.lib to the project directory and subjected it to Agner Fog's objconv as advised.
It's certainly moved things on because I'm now getting the messages shown.
I'm guessing they're other "missing" libraries that I need to objconv and copy (so as not to mess up the lib directory)
...I'll have a look.
Getting there!

[Linker Error] Error: Unresolved external '_GetStdHandle@4' referenced from C:\MY_DELPHI\MY_CBUILDER2006\PROJ4\MAS32_OMFD.LIB|stdout.obj
[Linker Error] Error: Unresolved external '_WriteFile@20' referenced from C:\MY_DELPHI\MY_CBUILDER2006\PROJ4\MAS32_OMFD.LIB|stdout.obj

qWord

It is strange that the kernel32.lib is not already involved in the link process - either use the kernel32.lib from the MASM32 SDK or the one that (probably) comes with your compiler/SDK/...
MREAL macros - when you need floating point arithmetic while assembling!


bobl

when I try to objconv kernel32.lib from masm32...using -fomf...I get

Input library: c:\my_delphi\my_cbuilder2006\proj4\kernel32.lib, Format: COFF, Ou
tput: omfd_kernel32.lib, Format: OMF
Error 2030: Unsupported relocation type (0)
Error 2030: Unsupported relocation type (0)
Error 2030: Unsupported relocation type (0)

C:\Documents and Settings\me\My Documents\Downloads\objconv>


Just a note to myself to say that although there's a kernel32.lib at "program files\Visual Studio...."
the one we're looking for now is here...C:\Program Files\Borland\BDS\4.0\lib\psdk

Edit:
I just added the lib using shift/F11 and I think these are the same errors

[Linker Error] Error: Unresolved external '_GetStdHandle@4' referenced from C:\MY_DELPHI\MY_CBUILDER2006\PROJ4\MAS32_OMFD.LIB|stdout.obj
[Linker Error] Error: Unresolved external '_WriteFile@20' referenced from C:\MY_DELPHI\MY_CBUILDER2006\PROJ4\MAS32_OMFD.LIB|stdout.obj


Just a thought...is there a c++ phrase (No of lines) I could try to exercise '_GetStdHandle@4' to rule out a faulty BDS2006 thing or my incompetetent installation of it(which it well may be)?

Edit:
I've just asked on Embacadero's forum if the above errors are known about.
It might be prudent to wait and see if this is some sort of known bug.