Beta D 2.069.0-b1

Szymon Gatner via Digitalmars-d-announce digitalmars-d-announce at puremagic.com
Wed Oct 14 05:57:24 PDT 2015


On Wednesday, 14 October 2015 at 12:35:30 UTC, Rainer Schuetze 
wrote:
>
> I just noticed that the magic symbol translation _snprintf -> 
> __snprintf isn't included without linking the internal function 
> init_msvc (which is normally done by d_run_main which is called 
> by the generated C main).
>
> The current workaround here is to add
>
> extern "C" void __cdecl init_msvc();
>
> to the C source and call it before rt_init. I think we should 
> move it into rt_init inside druntime.

This indeed helps, thanks!

There is new problem: creating a class instance on D side, then 
passing it to C++ and then back to D causes casting errors. My 
Example (based on Adam Ruppe's example):

C++ file:

#include <iostream>
#include <stdio.h>

extern "C" int rt_init();
extern "C" void rt_term();

extern "C++" int sumInD(int a, int b);
extern "C++" void printHelloInD();


class Operation {
public:

   virtual ~Operation() {}

   virtual int execute(int a, int b) = 0;
};

class Add : public Operation
{
   int execute(int a, int b) override
   {
     return a + b;
   }
};

extern "C++" void useOperation(Operation* t);
extern "C++" Operation* getSubtract();
extern "C++" void freeSubtract(Operation* cat);

struct DRuntime
{
   DRuntime()
   {
     if (!rt_init())\
     {
       throw std::runtime_error("D Initialization failed");
     }
   }

   ~DRuntime()
   {
     rt_term();
   }
};

void main()
{
   DRuntime druntime;
   Add add;

   useOperation(&add);

   Operation* sub = getSubtract();
   auto value = sub->execute(5, 3);
   freeSubtract(sub);

}

D library:

module lib;
import std.stdio;
import core.stdc.stdlib;

int main()
{
   return 0;
}

extern(C++)
interface Operation {
   void _destructorDoNotUse();
   int execute(int a, int b);
}
class Subtract : Operation {

   extern(C++)
     void _destructorDoNotUse() {}
   extern(C++)
     int execute(int a, int b) {return a - b;}
}

extern(C++)
Operation getSubtract() {
   import std.conv;
   enum size = __traits(classInstanceSize, Subtract);
   auto memory = malloc(size)[0 .. size];
   return emplace!Subtract(memory);
}

extern (C++) int sumInD(int a, int b)
{
   return a + b;
}

extern (C++) void printHelloInD()
{
   writeln("Hello From D!"); << ===== throws exception (bug 
reported)
}

extern(C++)
void freeSubtract(Operation animal) {
   auto cat = cast(Subtract) animal; <<====== cast yields null
   if(cat !is null) {
     destroy(cat);
     free(cast(void*) cat);
   }
}

extern(C++)
void useOperation(Operation t) {
   auto res = t.execute(1, 2);
}

Everything works fine except the marked line. Subtract instance 
seems to be created correctly on D side as it returns valid 
result in the execute() call on C++ side but then when trying to 
free the instance on D side again, downcast from Operation to 
Subtract fails resulting in null.




More information about the Digitalmars-d-announce mailing list