July 19, 2011
On 2011-07-19 00:56, Johann MacDonagh wrote:
> On 7/18/2011 5:04 PM, Andrej Mitrovic wrote:
>> On 7/18/11, Loopback<elliott.darfink@gmail.com> wrote:
>>> On 2011-07-18 21:59, Andrej Mitrovic wrote:
>>>> import core.dll_helper; is outdated, use import core.sys.windows.dll;
>>>> And also import core.runtime;
>>>
>>> Are there any examples covering these new modules, or are the procedure
>>> the same?
>>>
>>
>> It's all pretty much the same as the page says. There's a DLL example
>> in this folder:
>> \DMD\dmd2\samples\d\mydll
>
> Looks like VisualD's DLL template needs to be updated.
>
> FWIW I was able to compile and link a D DLL with the code I copy pasted
> in the other message.
>
> Loopback, do you have Visual Studio on your dev box? If so you should
> take a look at VisualD: http://www.dsource.org/projects/visuald
>
> Let us know if you're not able to compile a D DLL.

Thanks for all of your replies!

It seems as if the problem was solved by using core.sys.windows.dll
instead. Although I do have a bit of a problem. As I mentioned earlier
I wanted to make a DLL which C++ applications could interface with.

By making this possible, I have a "dll.d" file (just as the example) and
a "mydll.d" file - the file which implements the dll functions. In this
file, I have declared a function like this (testing purpose):

extern(C++) void SetInt(int * foo)
{
	*foo = 5;
}

When I compile this program with this DMD command line:
dmd -ofmydll.dll -L/IMPLIB mydll.d dll.d mydll.def

I get a successful compile, and a DLL file generated. For
some reason, I also get a ATA.lib file, which is exactly
1.00 KB big (any ideas why)?

The problem though, is related to the C++ side. I load the
DLL dynamically using "LoadLibraryA" function, and then
I try to load the SetInt function using GetProcAddress.

The LoadLibrary function succeeds but the GetProcAddress
function call fails saying that the function could not be
found.

typedef void (*PFGMO)(int*);

void main(int argc, char ** argv)
{
	// Function Pointer
	PFGMO pFGMO = NULL;

	HINSTANCE library;
	if((library = LoadLibraryA("C:\\mydll.dll")) == NULL)
		throw 1;

	bool result = (pFGMO = (PFGMO) GetProcAddress(library, "SetInt")) != NULL;

	// Result is zero (failed)
	std::cout << "Result: " << result;
	std::cin.get();
}

How come the procedure address cannot be found and how to solve it?
If of interest, this is the .def file (mydll.def)

LIBRARY "mydll.dll"
EXETYPE NT
SUBSYSTEM WINDOWS
CODE SHARED EXECUTE
DATA WRITE

When viewing the DLL with PE Explorer (program to explore executable
files) it reports that the number of symbols are zero. Is this related
to the problem perhaps?
July 19, 2011
You have several problems.

extern(C++) only specifies the calling convention, not the visibility of the symbol. To export the symbol, list it in a .def file or mark the function with export in the module itself, ala:

export extern(C++) void SetInt(int * foo) {}

I don't know why, but if you use a .def file instead of `export` the function will be exported as a C function with no name mangling.

Anyway, use a .def file like the one below and pass it to DMD while compiling the DLL, and it should be exported with that name (and change the string "mydll.dll" of course):

LIBRARY         "mydll.dll"
DESCRIPTION     'My DLL written in D'
EXETYPE		    NT
SUBSYSTEM       WINDOWS
CODE            PRELOAD DISCARDABLE
DATA            WRITE

EXPORTS
    SetInt


ATA.lib is probably the autogenerated import library which is useful for implicit linking.
July 19, 2011
On 7/18/2011 10:40 PM, Andrej Mitrovic wrote:
> You have several problems.
>
> extern(C++) only specifies the calling convention, not the visibility
> of the symbol. To export the symbol, list it in a .def file or mark
> the function with export in the module itself, ala:
>
> export extern(C++) void SetInt(int * foo) {}

If you export it like this, it will be exported as the C++ mangled name. If you have extern(C) it will be cdecl "_SetInt" and extern(Windows) will be stdcall "_SetInt@4".

> I don't know why, but if you use a .def file instead of `export` the
> function will be exported as a C function with no name mangling.

If you look at dumpbin /exports you'll see something like this:

    ordinal hint RVA      name

          1    0 0000306C SetInt = ?SetInt@@YAXPAH@Z (void __cdecl SetInt(int *))

So the symbol still has C++ name mangling but its exported as whatever name you want.
July 19, 2011
On 2011-07-19 04:40, Andrej Mitrovic wrote:
> You have several problems.
>
> extern(C++) only specifies the calling convention, not the visibility
> of the symbol. To export the symbol, list it in a .def file or mark
> the function with export in the module itself, ala:
>
> export extern(C++) void SetInt(int * foo) {}
>
> I don't know why, but if you use a .def file instead of `export` the
> function will be exported as a C function with no name mangling.
>
> Anyway, use a .def file like the one below and pass it to DMD while
> compiling the DLL, and it should be exported with that name (and
> change the string "mydll.dll" of course):
>
> LIBRARY         "mydll.dll"
> DESCRIPTION     'My DLL written in D'
> EXETYPE		    NT
> SUBSYSTEM       WINDOWS
> CODE            PRELOAD DISCARDABLE
> DATA            WRITE
>
> EXPORTS
>      SetInt
>
>
> ATA.lib is probably the autogenerated import library which is useful
> for implicit linking.
Seems as if this fixed it, thank you!

I want to ask though how I am supposed to go about to enable class
communication. For example; if I define a interface, and inherit this
interface in a class, C++ can use these class functions by defining
a analogous class (instead of interface) with virtual functions.

If I create a class dynamically on the heap (in my dll), and then
make a function that c++ can call to receive this object, how should
I proceed then?

extern(C++) interface Base
{
	int Test();
}

class Foo : Base
{
public:
	extern(C++) int Test() { return 5; }
}

export extern(C++) void GetObject(Base base)
{
	Foo temp = new Foo;
	base = Foo;
}

This is just a example to explain what I want to accomplish. One problem
with this code, is that a memory exception is thrown on the C++ side if
this function is called, whenever I use the "new" operator. Is this
because it's a export/extern function?

// C++ Code
class Base
{
public:
	virtual int Test(void);
};

What is the best method to accomplish this, and are there any
limitations with this method (do I have to allocate the class with
malloc instead etc.)?
July 19, 2011
On 7/18/2011 11:27 PM, Loopback wrote:
> On 2011-07-19 04:40, Andrej Mitrovic wrote:
>> You have several problems.
>>
>> extern(C++) only specifies the calling convention, not the visibility
>> of the symbol. To export the symbol, list it in a .def file or mark
>> the function with export in the module itself, ala:
>>
>> export extern(C++) void SetInt(int * foo) {}
>>
>> I don't know why, but if you use a .def file instead of `export` the
>> function will be exported as a C function with no name mangling.
>>
>> Anyway, use a .def file like the one below and pass it to DMD while
>> compiling the DLL, and it should be exported with that name (and
>> change the string "mydll.dll" of course):
>>
>> LIBRARY "mydll.dll"
>> DESCRIPTION 'My DLL written in D'
>> EXETYPE NT
>> SUBSYSTEM WINDOWS
>> CODE PRELOAD DISCARDABLE
>> DATA WRITE
>>
>> EXPORTS
>> SetInt
>>
>>
>> ATA.lib is probably the autogenerated import library which is useful
>> for implicit linking.
> Seems as if this fixed it, thank you!
>
> I want to ask though how I am supposed to go about to enable class
> communication. For example; if I define a interface, and inherit this
> interface in a class, C++ can use these class functions by defining
> a analogous class (instead of interface) with virtual functions.
>
> If I create a class dynamically on the heap (in my dll), and then
> make a function that c++ can call to receive this object, how should
> I proceed then?
>
> extern(C++) interface Base
> {
> int Test();
> }
>
> class Foo : Base
> {
> public:
> extern(C++) int Test() { return 5; }
> }
>
> export extern(C++) void GetObject(Base base)
> {
> Foo temp = new Foo;
> base = Foo;
> }
>
> This is just a example to explain what I want to accomplish. One problem
> with this code, is that a memory exception is thrown on the C++ side if
> this function is called, whenever I use the "new" operator. Is this
> because it's a export/extern function?
>
> // C++ Code
> class Base
> {
> public:
> virtual int Test(void);
> };
>
> What is the best method to accomplish this, and are there any
> limitations with this method (do I have to allocate the class with
> malloc instead etc.)?

Your C++ class "Base" is not compatible with your D "Foo" class. The v-tables are not guaranteed to be identical. I'm not even sure if D's thiscall is the same as C++'s thiscall. It's just not going to work. Most languages don't support this. This is why we use C bindings. Everyone supports C ;)

Now, you can do something like this:

struct Foo
{
	int x;
	float y;
}

extern(C) void* GetNewFoo()
{
	// Note: Don't use new here otherwise the GC may clean it up
	return cast(void*) core.memory.GC.malloc(Foo.sizeof);
}

extern(C) float Foo_DoSomething(Foo* foo)
{
	return foo.x + foo.y;
}

extern(C) void FreeFoo(Foo* foo)
{
	core.memory.GC.free(foo);
}

I haven't tried this, but something like this should work. Structs are inherently compatible between languages. Of course, you won't be able to do any kind of polymorphism.

Does this help?
July 19, 2011
On 7/19/11, Johann MacDonagh <johann.macdonagh.no@spam.gmail.com> wrote:
> If you export it like this, it will be exported as the C++ mangled name.
> If you have extern(C) it will be cdecl "_SetInt" and extern(Windows)
> will be stdcall "_SetInt@4".

Right, that's all pretty standard stuff. :)

>
>> I don't know why, but if you use a .def file instead of `export` the function will be exported as a C function with no name mangling.
>
> If you look at dumpbin /exports you'll see something like this:
>
>      ordinal hint RVA      name
>
>            1    0 0000306C SetInt = ?SetInt@@YAXPAH@Z (void __cdecl
> SetInt(int *))
>
> So the symbol still has C++ name mangling but its exported as whatever name you want.
>

See I tried using dumpbin, but apparently I wiped it from my PATH so I had to rely on DLL Export viewer (because I'm lazy and it had an icon on my desktop!) which doesn't even show this. I had a hunch that was happening behind the scenes. Thanks for the info regardless hehe.
July 19, 2011
Uhh, I tried using ASM to simulate the thiscall calling convention, it didn't go all to well. :) A wrapper C++ DLL that exposes a C interface was my workaround.

Here's a page that talks about some problems with passing objects via DLLs: http://www.prowiki.org/wiki4d/wiki.cgi?BestPractices/DLL
July 19, 2011
On 7/18/2011 11:52 PM, Andrej Mitrovic wrote:
> See I tried using dumpbin, but apparently I wiped it from my PATH so I
> had to rely on DLL Export viewer (because I'm lazy and it had an icon
> on my desktop!) which doesn't even show this. I had a hunch that was
> happening behind the scenes. Thanks for the info regardless hehe.

If you open a Visual Studio Command Prompt it should be in your PATH.

Also, you won't see the internal symbol name unless you have pdb symbols in the same directory as the DLL (VisualD converts the symbols for me, which is why I saw it).
July 19, 2011
On 2011-07-19 05:46, Johann MacDonagh wrote:
>>
>> What is the best method to accomplish this, and are there any
>> limitations with this method (do I have to allocate the class with
>> malloc instead etc.)?
>
> Your C++ class "Base" is not compatible with your D "Foo" class. The
> v-tables are not guaranteed to be identical. I'm not even sure if D's
> thiscall is the same as C++'s thiscall. It's just not going to work.
> Most languages don't support this. This is why we use C bindings.
> Everyone supports C ;)
>
> Now, you can do something like this:
>
> struct Foo
> {
> int x;
> float y;
> }
>
> extern(C) void* GetNewFoo()
> {
> // Note: Don't use new here otherwise the GC may clean it up
> return cast(void*) core.memory.GC.malloc(Foo.sizeof);
> }
>
> extern(C) float Foo_DoSomething(Foo* foo)
> {
> return foo.x + foo.y;
> }
>
> extern(C) void FreeFoo(Foo* foo)
> {
> core.memory.GC.free(foo);
> }
>
> I haven't tried this, but something like this should work. Structs are
> inherently compatible between languages. Of course, you won't be able to
> do any kind of polymorphism.
>
> Does this help?

Very interesting!

This might help depends; are you able to have structures with functions?
Are they still analogous if you implement them?

Also, how come the class-interface inheritance didn't work to
communicate with C++. Is the "Interface to C++" doc's outdated?

"Calling D Virtual Functions From C++"

http://www.digitalmars.com/d/2.0/cpp_interface.html
July 19, 2011
On 2011-07-19 12:39, Loopback wrote:
> On 2011-07-19 05:46, Johann MacDonagh wrote:
>>>
>>> What is the best method to accomplish this, and are there any
>>> limitations with this method (do I have to allocate the class with
>>> malloc instead etc.)?
>>
>> Your C++ class "Base" is not compatible with your D "Foo" class. The
>> v-tables are not guaranteed to be identical. I'm not even sure if D's
>> thiscall is the same as C++'s thiscall. It's just not going to work.
>> Most languages don't support this. This is why we use C bindings.
>> Everyone supports C ;)
>>
>> Now, you can do something like this:
>>
>> struct Foo
>> {
>> int x;
>> float y;
>> }
>>
>> extern(C) void* GetNewFoo()
>> {
>> // Note: Don't use new here otherwise the GC may clean it up
>> return cast(void*) core.memory.GC.malloc(Foo.sizeof);
>> }
>>
>> extern(C) float Foo_DoSomething(Foo* foo)
>> {
>> return foo.x + foo.y;
>> }
>>
>> extern(C) void FreeFoo(Foo* foo)
>> {
>> core.memory.GC.free(foo);
>> }
>>
>> I haven't tried this, but something like this should work. Structs are
>> inherently compatible between languages. Of course, you won't be able to
>> do any kind of polymorphism.
>>
>> Does this help?
>
> Very interesting!
>
> This might help depends; are you able to have structures with functions?
> Are they still analogous if you implement them?
>
> Also, how come the class-interface inheritance didn't work to
> communicate with C++. Is the "Interface to C++" doc's outdated?
>
> "Calling D Virtual Functions From C++"
>
> http://www.digitalmars.com/d/2.0/cpp_interface.html
I noticed that function seems to work functions with structures.
Are there any restrictions worth knowing or is it just like any other
structure when D and C++ communicate?

Can I have private variables, public, properties etc?

And just not to forget, why the C++ and interface class didn't work?
1 2
Next ›   Last »