Jump to page: 1 24  
Page
Thread overview
Accessing COM Objects
Jun 13, 2016
Incognito
Jun 13, 2016
Mike Parker
Jun 13, 2016
Incognito
Jun 13, 2016
Mike Parker
Jun 13, 2016
Mike Parker
Jun 13, 2016
John
Jun 13, 2016
Incognito
Jun 13, 2016
John
Jun 13, 2016
Incognito
Jun 14, 2016
Kagamin
Jun 14, 2016
John
Jun 15, 2016
Joerg Joergonson
Re: Accessing COM Objects P2
Jun 15, 2016
Joerg Joergonson
Re: Accessing COM Objects P3
Jun 15, 2016
Joerg Joergonson
Jun 15, 2016
John
Jun 15, 2016
John
Jun 15, 2016
Joerg Joergonson
Jun 15, 2016
John
Jun 15, 2016
Joerg Joergonson
Jun 15, 2016
John
Jun 15, 2016
Joerg Joergonson
Jun 17, 2016
thedeemon
Jun 17, 2016
John
Mar 11, 2017
Inquie
Mar 11, 2017
Inquie
Jun 15, 2016
thedeemon
Jun 15, 2016
Joerg Joergonson
Jun 15, 2016
thedeemon
Jun 15, 2016
Joerg Joergonson
Jun 15, 2016
Joerg Joergonson
Jun 15, 2016
John
Jun 15, 2016
Jesse Phillips
Jun 15, 2016
Joerg Joergonson
June 13, 2016
I've been reading over D's com and can't find anything useful. It seems there are different ways:

http://www.lunesu.com/uploads/ModernCOMProgramminginD.pdf

which is of no help and requires an idl file, which I don't have.

Then theres this

http://wiki.dlang.org/COM_Programming

which is also of no help:

import std.stdio;

import std.stdio, core.sys.windows.com, core.sys.windows.windows, std.exception, std.meta, std.traits;
import std.utf, core.stdc.stdlib, core.sys.windows.objidl, core.sys.windows.ole2;
pragma(lib, "ole32.lib");


GUID Guid(string str)()
{
    static assert(str.length==36, "Guid string must be 36 chars long");
    enum GUIDstring = "GUID(0x" ~ str[0..8] ~ ", 0x" ~ str[9..13] ~ ", 0x" ~ str[14..18] ~
        ", [0x" ~ str[19..21] ~ ", 0x" ~ str[21..23] ~ ", 0x" ~ str[24..26] ~ ", 0x" ~ str[26..28]
        ~ ", 0x" ~ str[28..30] ~ ", 0x" ~ str[30..32] ~ ", 0x" ~ str[32..34] ~ ", 0x" ~ str[34..36] ~ "])";
    return mixin(GUIDstring);
}

int main(string[] argv)
{

	// Adobe Photoshop App 9.0 CLSID {c09f153e-dff7-4eff-a570-af82c1a5a2a8}
	// Adobe Photoshop App 9.1 CLSID {6DECC242-87EF-11cf-86B4-444553540000}

	auto CLSID_DOMDocument60 = Guid!("6DECC242-87EF-11cf-86B4-444553540000");
	auto iid = IID_IUnknown;

	void* pUnk;
	auto hr = CoCreateInstance(&CLSID_DOMDocument60, null, CLSCTX_ALL, &iid, &pUnk);
	if (FAILED(hr))
		throw new Exception("Error!");

    writeln("Hello D-World!");
    return 0;
}

Maybe my CLSID's are wrong. Got them from the registry. The exception triggers each time. Even if it worked, I wouldn't know how to use it.

I can do this stuff in C# by simply dragging and dropping a dll into the references and it works fine but is a bit slow. I was hoping I could speed things up using D but it seems like COM isn't really supported, despite what several references say.

June 13, 2016
On Monday, 13 June 2016 at 01:22:33 UTC, Incognito wrote:

> I can do this stuff in C# by simply dragging and dropping a dll into the references and it works fine but is a bit slow. I was hoping I could speed things up using D but it seems like COM isn't really supported, despite what several references say.

Com *is* supported in D. I think it's better to work with interfaces rather than classes like the Wiki example:

interface MyCOMType : IUknown {}

Then when you get a pointer from CoCreateInstance or whatever, you cast it to the interface type and away you go.

In your code, your problem is that CoCreateInstance is failing, not that D doesn't support COM. It will help you to find out what the actual value of 'hr' is. Possible values are listed at [1].

[1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms686615(v=vs.85).aspx
June 13, 2016
On Monday, 13 June 2016 at 01:52:12 UTC, Mike Parker wrote:
> On Monday, 13 June 2016 at 01:22:33 UTC, Incognito wrote:
>
>> I can do this stuff in C# by simply dragging and dropping a dll into the references and it works fine but is a bit slow. I was hoping I could speed things up using D but it seems like COM isn't really supported, despite what several references say.
>
> Com *is* supported in D. I think it's better to work with interfaces rather than classes like the Wiki example:
>
> interface MyCOMType : IUknown {}
>
> Then when you get a pointer from CoCreateInstance or whatever, you cast it to the interface type and away you go.
>
> In your code, your problem is that CoCreateInstance is failing, not that D doesn't support COM. It will help you to find out what the actual value of 'hr' is. Possible values are listed at [1].
>
> [1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms686615(v=vs.85).aspx

What interface are you talking about? How can I cast to something I don't have? I do not have a photoshop COM interface. Are you saying that if CoCreateInstance worked that I can then use the iid or pUnk to access the COM? Do I get the members by trial and error? pUnk.width? Even if CoCreateInstance passed, what do I do next?


June 13, 2016
On Monday, 13 June 2016 at 02:08:22 UTC, Incognito wrote:

> What interface are you talking about? How can I cast to something I don't have? I do not have a photoshop COM interface. Are you saying that if CoCreateInstance worked that I can then use the iid or pUnk to access the COM? Do I get the members by trial and error? pUnk.width? Even if CoCreateInstance passed, what do I do next?

You have to define the interface yourself, extending from IUnknown, implementing whatever functions are available on the COM interface you want. Here's an example for the ID3D11Device interface:

https://github.com/auroragraphics/directx/blob/master/d3d11.d#L1332

June 13, 2016
On Monday, 13 June 2016 at 04:52:49 UTC, Mike Parker wrote:
> On Monday, 13 June 2016 at 02:08:22 UTC, Incognito wrote:
>
>> What interface are you talking about? How can I cast to something I don't have? I do not have a photoshop COM interface. Are you saying that if CoCreateInstance worked that I can then use the iid or pUnk to access the COM? Do I get the members by trial and error? pUnk.width? Even if CoCreateInstance passed, what do I do next?
>
> You have to define the interface yourself, extending from IUnknown, implementing whatever functions are available on the COM interface you want. Here's an example for the ID3D11Device interface:
>
> https://github.com/auroragraphics/directx/blob/master/d3d11.d#L1332

Sorry. Hit send too soon.

Once you've got your interface defined, you should be able to do this:

MyCOMType mct;
auto hr = CoCreateInstance(&CLSID_DOMDocument60, null, CLSCTX_ALL, &iid, &cast(void*)mct);

It's been a long time since I worked directly with COM, so there are probably details I'm missing, but this is the general idea.
June 13, 2016
On Monday, 13 June 2016 at 01:22:33 UTC, Incognito wrote:
> I've been reading over D's com and can't find anything useful. It seems there are different ways:
>
> http://www.lunesu.com/uploads/ModernCOMProgramminginD.pdf
>
> which is of no help and requires an idl file, which I don't have.
>
> Then theres this
>
> http://wiki.dlang.org/COM_Programming
>
> which is also of no help:
>
> import std.stdio;
>
> import std.stdio, core.sys.windows.com, core.sys.windows.windows, std.exception, std.meta, std.traits;
> import std.utf, core.stdc.stdlib, core.sys.windows.objidl, core.sys.windows.ole2;
> pragma(lib, "ole32.lib");
>
>
> GUID Guid(string str)()
> {
>     static assert(str.length==36, "Guid string must be 36 chars long");
>     enum GUIDstring = "GUID(0x" ~ str[0..8] ~ ", 0x" ~ str[9..13] ~ ", 0x" ~ str[14..18] ~
>         ", [0x" ~ str[19..21] ~ ", 0x" ~ str[21..23] ~ ", 0x" ~ str[24..26] ~ ", 0x" ~ str[26..28]
>         ~ ", 0x" ~ str[28..30] ~ ", 0x" ~ str[30..32] ~ ", 0x" ~ str[32..34] ~ ", 0x" ~ str[34..36] ~ "])";
>     return mixin(GUIDstring);
> }
>
> int main(string[] argv)
> {
>
> 	// Adobe Photoshop App 9.0 CLSID {c09f153e-dff7-4eff-a570-af82c1a5a2a8}
> 	// Adobe Photoshop App 9.1 CLSID {6DECC242-87EF-11cf-86B4-444553540000}
>
> 	auto CLSID_DOMDocument60 = Guid!("6DECC242-87EF-11cf-86B4-444553540000");
> 	auto iid = IID_IUnknown;
>
> 	void* pUnk;
> 	auto hr = CoCreateInstance(&CLSID_DOMDocument60, null, CLSCTX_ALL, &iid, &pUnk);
> 	if (FAILED(hr))
> 		throw new Exception("Error!");
>
>     writeln("Hello D-World!");
>     return 0;
> }
>
> Maybe my CLSID's are wrong. Got them from the registry. The exception triggers each time. Even if it worked, I wouldn't know how to use it.
>
> I can do this stuff in C# by simply dragging and dropping a dll into the references and it works fine but is a bit slow. I was hoping I could speed things up using D but it seems like COM isn't really supported, despite what several references say.

COM is supported in D. The difference is that C# hides all the plumbing behind nice classes.

You're going to need Photoshop's COM interface to do anything with it. If you don't have a C header that you can translate into D, you could use a tool included in the Windows SDK called OleView. It will peek inside COM  libraries and give you the interface definitions.

As to why CoCreateInstance isn't working, make sure you're calling CoInitialize or CoInitializeEx beforehand. If it's still failing, use std.windows.syserror.sysErrorString(hr) to see if it gives you a reason. Otherwise, CLSCTX_ALL might be the culprit - try using CLSCTX_SERVER instead.
June 13, 2016
On Monday, 13 June 2016 at 07:40:09 UTC, John wrote:
> On Monday, 13 June 2016 at 01:22:33 UTC, Incognito wrote:
>> I've been reading over D's com and can't find anything useful. It seems there are different ways:
>>
>> http://www.lunesu.com/uploads/ModernCOMProgramminginD.pdf
>>
>> which is of no help and requires an idl file, which I don't have.
>>
>> Then theres this
>>
>> http://wiki.dlang.org/COM_Programming
>>
>> which is also of no help:
>>
>> import std.stdio;
>>
>> import std.stdio, core.sys.windows.com, core.sys.windows.windows, std.exception, std.meta, std.traits;
>> import std.utf, core.stdc.stdlib, core.sys.windows.objidl, core.sys.windows.ole2;
>> pragma(lib, "ole32.lib");
>>
>>
>> GUID Guid(string str)()
>> {
>>     static assert(str.length==36, "Guid string must be 36 chars long");
>>     enum GUIDstring = "GUID(0x" ~ str[0..8] ~ ", 0x" ~ str[9..13] ~ ", 0x" ~ str[14..18] ~
>>         ", [0x" ~ str[19..21] ~ ", 0x" ~ str[21..23] ~ ", 0x" ~ str[24..26] ~ ", 0x" ~ str[26..28]
>>         ~ ", 0x" ~ str[28..30] ~ ", 0x" ~ str[30..32] ~ ", 0x" ~ str[32..34] ~ ", 0x" ~ str[34..36] ~ "])";
>>     return mixin(GUIDstring);
>> }
>>
>> int main(string[] argv)
>> {
>>
>> 	// Adobe Photoshop App 9.0 CLSID {c09f153e-dff7-4eff-a570-af82c1a5a2a8}
>> 	// Adobe Photoshop App 9.1 CLSID {6DECC242-87EF-11cf-86B4-444553540000}
>>
>> 	auto CLSID_DOMDocument60 = Guid!("6DECC242-87EF-11cf-86B4-444553540000");
>> 	auto iid = IID_IUnknown;
>>
>> 	void* pUnk;
>> 	auto hr = CoCreateInstance(&CLSID_DOMDocument60, null, CLSCTX_ALL, &iid, &pUnk);
>> 	if (FAILED(hr))
>> 		throw new Exception("Error!");
>>
>>     writeln("Hello D-World!");
>>     return 0;
>> }
>>
>> Maybe my CLSID's are wrong. Got them from the registry. The exception triggers each time. Even if it worked, I wouldn't know how to use it.
>>
>> I can do this stuff in C# by simply dragging and dropping a dll into the references and it works fine but is a bit slow. I was hoping I could speed things up using D but it seems like COM isn't really supported, despite what several references say.
>
> COM is supported in D. The difference is that C# hides all the plumbing behind nice classes.
>
> You're going to need Photoshop's COM interface to do anything with it. If you don't have a C header that you can translate into D, you could use a tool included in the Windows SDK called OleView. It will peek inside COM  libraries and give you the interface definitions.
>
> As to why CoCreateInstance isn't working, make sure you're calling CoInitialize or CoInitializeEx beforehand. If it's still failing, use std.windows.syserror.sysErrorString(hr) to see if it gives you a reason. Otherwise, CLSCTX_ALL might be the culprit - try using CLSCTX_SERVER instead.


Cool. Oleview gives me the idl files. How to convert the idl files to d or possibly c?

Would I just use them in place of IUnknown once I have the interface?

June 13, 2016
On Monday, 13 June 2016 at 17:38:41 UTC, Incognito wrote:
> Cool. Oleview gives me the idl files. How to convert the idl files to d or possibly c?
>
> Would I just use them in place of IUnknown once I have the interface?

In OleView you can save the IDL file, then run another tool, midl.exe, on the IDL file. That will generate the C headers. But you'd then have to translate that to D by hand.

I have written a tool that takes a COM type library and automatically converts it to a D source file. I could finish it off over the next few days and put the source on GitHub if you're interested.
June 13, 2016
On Monday, 13 June 2016 at 19:11:59 UTC, John wrote:
> On Monday, 13 June 2016 at 17:38:41 UTC, Incognito wrote:
>> Cool. Oleview gives me the idl files. How to convert the idl files to d or possibly c?
>>
>> Would I just use them in place of IUnknown once I have the interface?
>
> In OleView you can save the IDL file, then run another tool, midl.exe, on the IDL file. That will generate the C headers. But you'd then have to translate that to D by hand.
>
> I have written a tool that takes a COM type library and automatically converts it to a D source file. I could finish it off over the next few days and put the source on GitHub if you're interested.

That would be great! With it I might be able to put a nice wrapper around Photoshop for use with D. Others mind find it useful too as other programs still use COM.




June 14, 2016
Visual D has a tool to convert IDL files to D.
« First   ‹ Prev
1 2 3 4