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