English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. C/C++ (https://eab.abime.net/forumdisplay.php?f=118)
-   -   SAS/C and extern "C" (https://eab.abime.net/showthread.php?t=88077)

emufan 29 July 2017 00:56

SAS/C and extern "C"
 
i made some progress with the LW plugins, but I cannot convert some c++ function to c.

so the problem with original c++ source: SAS/C compiles the code only,
if I remove the extern "C" blocks - resulting binary is not working with LW.

if i compile with the extern "C" blocks it give some overloaded function errors.

smakefile, i'm using:
Code:

UINC    = /SDK/include/
ULIB    = /SDK/lib/
CFLAGS  = cpu=68020 math=68881 nostkchk idir=$(UINC) idir=cxxinclude

blink.p: blink.o
        sc link $(CFLAGS) startup=$(ULIB)serv_s.o $(ULIB)server.lib \
        blink.o pname=$@
blink.o:
        sc $(CFLAGS) blink.cc
all : blink.p

attached is the original source file, written for the SGI version of LW5.
can anyone explain what is wrong with extern "C" blocks ?

a/b 29 July 2017 01:25

First you declare them as c functions (lines 18-36). Then you implement them as c++ functions (lines 80+).
Did you try to put the entire implementation, lines 80-285, inside extern "C"?

EDIT: OK, I'm checking those functions. They actually are in c++. You will probably need c wrappers that call c++ counterparts. Something like:
Code:

LWInstance create_impl(LWError *error)
{
// actual implementation
}

extern "C" {
LWInstance create(LWError *error)
{ return create_impl(error); }
...

} // extern "C"

Another option could be to change calling convention for those c++ functions, but I'm not experienced enough with sas/c to tell how exactly.

emufan 29 July 2017 01:58

thanks for your help :)
these plugins were written in 96/97 - C++98 was not yet the standard, i guess.
and i did not wrote the code, i just found the old sources :)

I made the "lines 80-285" block, but i get the same overloaded error.
i'm not sure about the wrapper or how to write the "actual implementation" code.

but it's rather strange, sasc does build the binary, if the extern "C" is removed,
so i thought it is possble to fix this issue first.

the blink.lnk file:
Code:

FROM /SDK/lib/serv_s.o "blink.o"
TO "blink.p"
LIB /SDK/lib/server.lib LIB:scm881.lib
    LIB:sc.lib LIB:amiga.lib

it is just scm sc and not scxx scxxm libs. so this can explain why the final binary cannot work?

i attached the source + includes + lw linker libs, if anyone wants try local..

alkis 29 July 2017 10:08

extern "C" is usefull when you want to link functions defined in a cpp module with C (or asm or whatever) code.

This code doesn't get linked in such a way. (If it was, you'd get linker errors in linking)

By that logic, you don't need extern "C".

As you said, sasc compiles and links the code if you remove extern "C". But you don't get a working plugin.

Your last chance is wrapping the return type of each function with the XCALL_() macro

i.e
int foo(whatever) turns into XCALL_(int) foo(whatever)

emufan 29 July 2017 15:46

1 Attachment(s)
so SASC is not the appropriate compiler for the (given) c++ code.

I went back to gxx 2.95.3, on the cygwin32 system ( crosscompiler).
the only error i get is the missing "-lm" while linking.

verbose output w/o definition part:
Code:

$ m68k-amigaos-g++.exe  -Iinclude blink.cc
...
GNU CPP version 2.95.3 20010315 (release) (68k, MIT syntax)
#include "..." search starts here:
#include <...> search starts here:
 include
 /opt/m68k-amigaos/lib/gcc-lib/m68k-amigaos/2.95.3/include/g++
 /opt/m68k-amigaos/lib/gcc-lib/m68k-amigaos/2.95.3/include
 /opt/m68k-amigaos/lib/gcc-lib/m68k-amigaos/2.95.3/../../../../m68k-amigaos/include/../include
 /opt/m68k-amigaos/lib/gcc-lib/m68k-amigaos/2.95.3/../../../../m68k-amigaos/include/../ndk/include
 /opt/m68k-amigaos/lib/gcc-lib/m68k-amigaos/2.95.3/../../../../m68k-amigaos/sys-include
End of search list.
The following default directories have been omitted from the search path:
End of omitted list.
 /opt/m68k-amigaos/lib/gcc-lib/m68k-amigaos/2.95.3/cc1plus /tmp/ccMt00Up.ii -quiet -dumpbase blink.cc -m68020 -m68881 -version -o /tmp/ccV4uK2j.s
GNU C++ version 2.95.3 20010315 (release) (m68k-amigaos) compiled by GNU C version 5.4.0.
blink.cc: In function `unsigned int flags(void *)':
blink.cc:285: warning: converting NULL to non-pointer type
 /opt/m68k-amigaos/m68k-amigaos/bin/as -mc68020 -o /tmp/ccS3uxt5.o /tmp/ccV4uK2j.s
 /opt/m68k-amigaos/lib/gcc-lib/m68k-amigaos/2.95.3/collect2 -fl libm020 -fl libm881 -L/opt/m68k-amigaos/lib/gcc-lib/m68k-amigaos/2.95.3/libm020 -L/opt/m68k-amigaos/lib/gcc-lib/m68k-amigaos/2.95.3 -L/opt/m68k-amigaos/m68k-amigaos/lib/libm020 -L/opt/m68k-amigaos/m68k-amigaos/lib /tmp/ccS3uxt5.o -lstdc++ -lm -lgcc
/opt/m68k-amigaos/m68k-amigaos/bin/ld: cannot open -lm: No such file or directory
collect2: ld returned 1 exit status

which math lib does the compiler look for?

#2) XCALL_ macro:
so i should wrap any variable in the original extern "C" block with this macro?

#3) good progress with SASC and converting to C.
initial values seems wrong, so there are still some bugs,
but the plugin panel opens for the first time.

i can change values and rendering with the active plugin does not crash LW.

#4) if i get it right, this plugin is a big thing, since it makes it possible to animate
different values over time, which is not possible for Surface parameters in LW5.

emufan 29 July 2017 19:30

so now I will verify my C++ to C conversation:

LUMINOUS i gave random value of 100, it is member of an enum,
maybe it should be 0 or 1:
Code:

enum CHANNELS { LUMINOUS, DIFFUSE, SPECULAR, MIRROR, TRANSP };
original c++:
Code:

class BLINKER
{
public:
        BLINKER() : frame(0), period(30), fPer1(100), fPer2(0), uChannel(LUMINOUS) {}
        LWFrame frame;
        unsigned int period;
        unsigned short int uChannel;
        float fPer1, fPer2;
private:

};

C version:
Code:

LWFrame frame = 0;
unsigned int period = 30;
unsigned short int uChannel = 100;
float fPer1 = 100;
float fPer2 = 0;

typedef struct BLINKER_TAG{
        LWFrame frame,
        period,
        fPer1,
        fPer2,
        uChannel;
}BLINKER;

is this correct?

alkis 29 July 2017 20:39

not really, you have all the members in BLINKER typedef being of type LWFrame.
should be more like

Code:

typedef struct BLINKER_TAG{
  LWFrame frame;
  unsigned int period;
  unsigned short int uChannel;
  float fPer1;
  float fPer2;
}BLINKER;


emufan 29 July 2017 21:51

ah, thank you, the comma fault.
but it does compile, w/o error/warning, strange.

result is the same, must be something else :)

alkis 29 July 2017 22:25

Please attach c source code.

emufan 29 July 2017 23:02

1 Attachment(s)
Quote:

Originally Posted by alkis (Post 1175038)
Please attach c source code.

is attached in initial post - it's the original c++ source.

i also made some good progress with goo, also converted to C,
disabled those c++ functions I dont understand.

for now it starts in LW and option panel is working :D

problem is for sure some pointer, things i dont understand: * value , (value), *(value) and those things.
the initial values in the source are simply wrong, in the option panel of the plugins.

alkis 29 July 2017 23:45

initial post has the c++ code and not the c code. Unless, I am overseeing something.

emufan 30 July 2017 00:29

Quote:

Originally Posted by alkis (Post 1175055)
initial post has the c++ code and not the c code. Unless, I am overseeing something.

i think it would be easier to start with the c++ src.
i made for sure some mistakes with definitions and stuff,
so compare it with the original.
fresnel.c is of good use too, so you can compare how they made some
calls and definitions.

alkis 30 July 2017 01:28

1 Attachment(s)
Any chance this works?

emufan 30 July 2017 02:31

Quote:

Originally Posted by alkis (Post 1175067)
Any chance this works?

oh, yes :D

i have to figure out, what it is really about, but it seems working :)
thanks alot :great

#1) while we are at it, attached is the goo source. my WIP and the original.
if you still have some minutes :)

#2) original had a header file, but i'm not sure if it's really needed.

#3) one thing does not work.
if you setup a scene with a plugin and save the scene,
you should have an entry in the scene file, with the plugin descsription and values set.
this does not work.
i'm not sure which of the API functions do this.
i'll have a look and compare with some other working plugins.

#4) i included LWGlobals.hh in goo-WIP.c, but there are some undeclared things i dont understand.

emufan 01 August 2017 17:47

I have another plugin: RGBshift. almost done using the working blink source :)

i can build and use it, but initial values are wrong again.
it does not work when applied to a scene.
original and my WIP attached.

#1) fixed. just one XCALL_ was missing. :)

emufan 02 August 2017 15:32

i've converted a class to typedef struct.
the class is called at one occasion, so i'm not sure, how it has to be initialized in C:
C++ original:
Code:

class callback
{
public:
        LWPanelFuncs        *panel;
        LWPanelID        panelid;
        STATIMAGE        *user;
private:
};
...
callback *udata = new callback;

C translated:
Code:

typedef  struct callback_TAG
{
        LWPanelFuncs    *panel;
        LWPanelID      panelid;
        STATIMAGE      *user;
}callback;
...
callback *udata;

is this correct?

Leffmann 03 August 2017 13:35

If there's nothing more to that class then you can just do
callback *udata = malloc(sizeof (callback));
, and for
delete callback;
you do
free(callback);
.

EDIT: it should be
delete udata;
and
free(udata);

emufan 03 August 2017 14:12

thanks, but this doesnt change the problem here.
there is an info panel, with some sub panels, callback is used to have a "callback",
for safe return from sub to main panel.
but lw crashs when i press "ok" or "cancel" on the sub panel.

i thought is is due to bad forming of the callback structure.
but i guess it is something else, i didnt find yet.

btw. does it matter,if i'm using "(sizeof (callback)" or "(sizeof (callback_TAG)"?

emufan 03 August 2017 15:39

there is an important part in the LW plugins, those save/load function.
original c++:
Code:

VIDIMAGE *saveptr = (VIDIMAGE *)(inst);

char saveline[64];
ostrstream ostr(saveline,64);

for (int i=0; i<64; i++) saveline[i]='\0';

ostr << saveptr->spln << " ";
ostr << saveptr->dirn << " ";
ostr << saveptr->thickness << " ";
ostr << saveptr->darken << " ";
ostr << saveptr->brighten;

// Now write the data into the file...
lwss->write(lwss->writeData, saveline, 64);

need to rewrite this in c - exchanged the ostr calls:
Code:

const char * const SPACE = " ";

strcpy (saveline, saveptr->spln); strcpy (saveline, SPACE);
strcpy (saveline, saveptr->dirn); strcpy (saveline, SPACE);
strcpy (saveline, saveptr->thickness); strcpy (saveline, SPACE);
strcpy (saveline, saveptr->darken); strcpy (saveline, SPACE);
strcpy (saveline, saveptr->brighten);

VIDIMAGE is a struct like the callback above.

it does build, but does not accomplish the same.
next is from lw scene file, there should be some values in the blank line.
Code:

Plugin ImageFilterHandler 1 T42_Vidlines

EndPlugin

any idea how to make it work?

alkis 03 August 2017 17:15

Well, from blinkc.c

Code:

//Load function.
//
XCALL_(LWError) load(LWInstance *inst, const LWLoadState *lwls)
{
        BLINKER *defInst = (BLINKER*)(inst);
        BLINKER cData;
        lwls->read(lwls->readData, (char *)&cData, sizeof(BLINKER));
        *defInst = cData;
        return (NULL);
}


//Save function.
XCALL_(LWError) save(LWInstance *inst, const LWSaveState *lwss)
{
        BLINKER *defInst = (BLINKER *)(inst);
        BLINKER cData;
        cData = *defInst;
        lwss->write(lwss->writeData, (char *)&cData, sizeof(BLINKER));
        return (NULL);
}

replace BLINKER with the new 'type' (VIDIMAGE I guess)


All times are GMT +2. The time now is 08:41.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.04873 seconds with 11 queries