Re: Accessing COM Objects

2017-03-10 Thread Inquie via Digitalmars-d-learn

On Friday, 17 June 2016 at 08:09:42 UTC, John wrote:
On Wednesday, 15 June 2016 at 21:06:01 UTC, Joerg Joergonson 
wrote:
My thinking is that CoCreateinstance is suppose to give us a 
pointer to the interface so we can use it, if all this stuff 
is crashing does that mean the interface is invalid or not 
being assigned properly or is there far more to it than this?


The problem is Photoshop hasn't provided an interface with 
methods that can be called directly. They don't exist on the 
interface, hence them being commented out. It's a mechanism 
known as late binding (everything is done at runtime rather 
than compile time). You need to ask the interface for the 
method's ID, marshal the parameters into a specific format, and 
then "invoke" the method using that ID.


And you're not going to like it. Here's an example just to call 
the "Load" method:


  // Initialize the Photoshop class instance
  IDispatch psApp;
  auto iid = IID__Application;
  auto clsid = CLSID_Application;
  assert(SUCCEEDED(CoCreateInstance(, null, CLSCTX_ALL, 
, cast(void**;

  scope(exit) psApp.Release();

  // Get the ID of the Load method
  auto methodName = "Load"w.ptr;
  auto dispId = DISPID_UNKNOWN;
  iid = IID_NULL;
  assert(SUCCEEDED(psApp.GetIDsOfNames(, , 1, 0, 
)));


  // Put the parameters into the expected format
  VARIANT fileName = {
vt: VARENUM.VT_BSTR,
bstrVal: SysAllocString("ps.psd"w.ptr)
  };
  scope(exit) VariantClear();

  DISPPARAMS params = {
rgvarg: ,
cArgs: 1
  };

  // Finally call the method
  assert(SUCCEEDED(psApp.Invoke(dispId, , 0, 
DISPATCH_METHOD, , null, null, null)));


tlb2d only outputs the late-bound methods as a hint to the user 
so they know the names of the methods and the expected 
parameters (well, it saves looking them up in OleView). Had 
Photoshop supplied a compile-time binding, you could have just 
called psApp.Load(fileName) like you tried.


It's possible to wrap that ugly mess above in less verbose code 
using native D types, and the Juno COM library mentioned 
earlier enabled that, but the code is quite ancient (and is 
part of and depends on a larger library). I've been slowly 
working on a more modern library. You'd be able to just write 
this:


  auto psApp = makeReference!"Photoshop.Application"();
  psApp.Load("ps.psd");

But I don't know when it'll be ready.


So, I was playing around with this method and was able to get 
things to work. Have you been able to automate this properly? 
Seems like if we have the interface and methods, we can create an 
implementation that automates the above marshaling and stuff 
automatically using reflection?


e.g., give

interface _Application : IDispatch {
...
  /*[id(0x4C64536C)]*/ void Load(BSTR Document);
...
  /*[id(0x71756974)]*/ void Quit();
...
}

it shouldn't be too hard to generate a class like

Generated code:

class PSAppication : _Application
{
...
void Load(BSTR Document)
{
   // The invoking and marshaling code automatically 
generated //

}
...
void Quit()
{
   // The invoking and marshaling code automatically 
generated //

}

...
}

? I assume this is what you said you were working on, more or 
less? Would be awesome if you already had this up and running! If 
not, I guess I'll try to implement something like it ;/



If you haven't worked on this, I have a few questions for ya:

1. Do we have to cocreateinit every time or can we just do it 
once? Seems like it could be a major performance issue if we have 
to call it each time?


2. Marshaling the paramters seems like it could be tricky as we 
would have to know each case? Scanning the photoshop idl file 
suggests there are many different parameter and return 
types(strings, ints, VARIANT_BOOL, com interfaces, enum, etc).


A few are easy to handle and you showed how to handle strings, 
but some of the others I wouldn't know how to do.


3. Does the juno code handle this well enough to copy and paste 
most of the labor?


4. Any pitfalls to worry about?

Thanks.



Re: Accessing COM Objects

2017-03-10 Thread Inquie via Digitalmars-d-learn

On Friday, 17 June 2016 at 08:09:42 UTC, John wrote:
On Wednesday, 15 June 2016 at 21:06:01 UTC, Joerg Joergonson 
wrote:

[...]


The problem is Photoshop hasn't provided an interface with 
methods that can be called directly. They don't exist on the 
interface, hence them being commented out. It's a mechanism 
known as late binding (everything is done at runtime rather 
than compile time). You need to ask the interface for the 
method's ID, marshal the parameters into a specific format, and 
then "invoke" the method using that ID.


[...]



Any news on this? I'd like to do some photoshop programming in D 
too but it seems like a mess?!?


Re: Accessing COM Objects

2016-06-17 Thread John via Digitalmars-d-learn
On Wednesday, 15 June 2016 at 21:06:01 UTC, Joerg Joergonson 
wrote:
My thinking is that CoCreateinstance is suppose to give us a 
pointer to the interface so we can use it, if all this stuff is 
crashing does that mean the interface is invalid or not being 
assigned properly or is there far more to it than this?


The problem is Photoshop hasn't provided an interface with 
methods that can be called directly. They don't exist on the 
interface, hence them being commented out. It's a mechanism known 
as late binding (everything is done at runtime rather than 
compile time). You need to ask the interface for the method's ID, 
marshal the parameters into a specific format, and then "invoke" 
the method using that ID.


And you're not going to like it. Here's an example just to call 
the "Load" method:


  // Initialize the Photoshop class instance
  IDispatch psApp;
  auto iid = IID__Application;
  auto clsid = CLSID_Application;
  assert(SUCCEEDED(CoCreateInstance(, null, CLSCTX_ALL, 
, cast(void**;

  scope(exit) psApp.Release();

  // Get the ID of the Load method
  auto methodName = "Load"w.ptr;
  auto dispId = DISPID_UNKNOWN;
  iid = IID_NULL;
  assert(SUCCEEDED(psApp.GetIDsOfNames(, , 1, 0, 
)));


  // Put the parameters into the expected format
  VARIANT fileName = {
vt: VARENUM.VT_BSTR,
bstrVal: SysAllocString("ps.psd"w.ptr)
  };
  scope(exit) VariantClear();

  DISPPARAMS params = {
rgvarg: ,
cArgs: 1
  };

  // Finally call the method
  assert(SUCCEEDED(psApp.Invoke(dispId, , 0, DISPATCH_METHOD, 
, null, null, null)));


tlb2d only outputs the late-bound methods as a hint to the user 
so they know the names of the methods and the expected parameters 
(well, it saves looking them up in OleView). Had Photoshop 
supplied a compile-time binding, you could have just called 
psApp.Load(fileName) like you tried.


It's possible to wrap that ugly mess above in less verbose code 
using native D types, and the Juno COM library mentioned earlier 
enabled that, but the code is quite ancient (and is part of and 
depends on a larger library). I've been slowly working on a more 
modern library. You'd be able to just write this:


  auto psApp = makeReference!"Photoshop.Application"();
  psApp.Load("ps.psd");

But I don't know when it'll be ready.


Re: Accessing COM Objects

2016-06-16 Thread thedeemon via Digitalmars-d-learn
On Wednesday, 15 June 2016 at 21:06:01 UTC, Joerg Joergonson 
wrote:

Ok, I've tried things like uncommenting

	Document Open(BSTR Document, VARIANT As, VARIANT 
AsSmartObject);

void Load(BSTR Document);

/*[id(0x70537673)]*/ BSTR get_ScriptingVersion();
  /*[id(0x70464D4D)]*/ double get_FreeMemory();
  /*[id(0x76657273)]*/ BSTR get_Version();
and everything crashes with bad reference.
...
My thinking is that CoCreateinstance is suppose to give us a 
pointer to the interface so we can use it, if all this stuff is 
crashing does that mean the interface is invalid or not being 
assigned properly or is there far more to it than this?


First of all, you can't just comment/uncomment parts of COM 
interface descriptions. Each COM interface has some specific 
layout of its functions, and if you list them in wrong order or 
skip some of them the virtual methods table gets completely 
screwed up, so you think you call one method but end up calling 
another, because you intended to call method #12 and instead 
called method #4. COM interface definitions in D must match their 
definitions in IDL exactly. One omission of a method, one mistake 
in its type, and you're fucked.


Re: Accessing COM Objects

2016-06-15 Thread Joerg Joergonson via Digitalmars-d-learn

On Wednesday, 15 June 2016 at 19:21:51 UTC, John wrote:
On Wednesday, 15 June 2016 at 18:32:28 UTC, Joerg Joergonson 
wrote:

  import core.sys.windows.com, core.sys.windows.oaidl;


Thanks. Should these not be added to the generated file?


The problem is that other type libraries will probably require 
other headers to be imported, and there's no way to work out 
which, so I've left that up to the user for now.




Also, could you add to it the following:

const static GUID iid = 
Guid!("5DE90358-4D0B-4FA1-BA3E-C91BBA863F32");


inside the interface (Replace the string with the correct 
guid)?




This allows it to work with ComPtr which looks for the iid 
inside the interface, shouldn't hurt anything.


I could add that as an option.



In any case, I haven't got ComPtr to work so...


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);
}




also tried CoCreateInstance and getting error 80040154

Not sure if it works.



Changed the GUID to another one found in the registry(not the 
one at the top of the generated file) and it works. Both load 
photoshop


Oops. The one at the top of the file is the type library's ID, 
not the class ID. I should just omit it if it causes confusion.





int main(string[] argv)
{

//auto ps = ComPtr!_Application(CLSID_PS).require;

	//const auto CLSID_PS = 
Guid!("6DECC242-87EF-11cf-86B4-44455354"); // PS 90.1 
fails because of interface issue
	const auto CLSID_PS = 
Guid!("c09f153e-dff7-4eff-a570-af82c1a5a2a8");   // PS 90.0 
works.





auto hr = CoInitialize(null);
auto iid = IID__Application;


_Application* pUnk;

hr = CoCreateInstance(_PS, null, CLSCTX_ALL, , 
cast(void**));

if (FAILED(hr))
throw new Exception("ASDF");

}

The photoshop.d file
http://www.filedropper.com/photoshop_1


So, I guess it works but how to access the methods? The 
photoshop file looks to have them listed but they are all 
commented out.


They're commented out because Photoshop seems to have only 
provided a late-binding interface and you have to call them by 
name through IDispatch.Invoke. It's possible to wrap all that 
in normal D methods, and I'm working on it, but it won't be 
ready for a while.



Ok, I've tried things like uncommenting

Document Open(BSTR Document, VARIANT As, VARIANT AsSmartObject);
void Load(BSTR Document);

/*[id(0x70537673)]*/ BSTR get_ScriptingVersion();
  /*[id(0x70464D4D)]*/ double get_FreeMemory();
  /*[id(0x76657273)]*/ BSTR get_Version();
and everything crashes with bad reference.



If I try ComPtr, same thing



	const auto CLSID_PS = 
Guid!("c09f153e-dff7-4eff-a570-af82c1a5a2a8");   // PS 90.0 works.





auto hr = CoInitialize(null);
auto iid = IID__Application;

 	auto ps = 
cast(_Application)(ComPtr!_Application(CLSID_PS).require);


_Application pUnk;

hr = CoCreateInstance(_PS, null, CLSCTX_ALL, , 
cast(void**));

if (FAILED(hr))
throw new Exception("ASDF");

auto ptr = cast(wchar*)alloca(wchar.sizeof * 1000);

auto fn = `ps.psd`;
for(auto i = 0; i < fn.length; i++)
{
ptr[i] = fn[i];
}

writeln(ps.get_FreeMemory());

pUnk.Load(ptr);



My thinking is that CoCreateinstance is suppose to give us a 
pointer to the interface so we can use it, if all this stuff is 
crashing does that mean the interface is invalid or not being 
assigned properly or is there far more to it than this?




(


Re: Accessing COM Objects

2016-06-15 Thread John via Digitalmars-d-learn
On Wednesday, 15 June 2016 at 18:35:42 UTC, Joerg Joergonson 
wrote:

On Wednesday, 15 June 2016 at 06:09:33 UTC, thedeemon wrote:

On Monday, 13 June 2016 at 17:38:41 UTC, Incognito wrote:


[...]


There are ready tools idl2d:
https://github.com/dlang/visuald/tree/master/c2d

[...]


I can't seem to get ComPtr to work.


auto ps = ComPtr!_Application(CLSID_PS).require;

Where CLSID_PS is the Guid from the registry that seems to work 
with CoCreate. _Application was generated from tbl2d.



See my other post for a more(not much) complete description of 
the issues files.


Ensure you are calling CoInitialize before anything else.


Re: Accessing COM Objects

2016-06-15 Thread John via Digitalmars-d-learn
On Wednesday, 15 June 2016 at 18:32:28 UTC, Joerg Joergonson 
wrote:

  import core.sys.windows.com, core.sys.windows.oaidl;


Thanks. Should these not be added to the generated file?


The problem is that other type libraries will probably require 
other headers to be imported, and there's no way to work out 
which, so I've left that up to the user for now.




Also, could you add to it the following:

const static GUID iid = 
Guid!("5DE90358-4D0B-4FA1-BA3E-C91BBA863F32");


inside the interface (Replace the string with the correct guid)?



This allows it to work with ComPtr which looks for the iid 
inside the interface, shouldn't hurt anything.


I could add that as an option.



In any case, I haven't got ComPtr to work so...


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);
}




also tried CoCreateInstance and getting error 80040154

Not sure if it works.



Changed the GUID to another one found in the registry(not the 
one at the top of the generated file) and it works. Both load 
photoshop


Oops. The one at the top of the file is the type library's ID, 
not the class ID. I should just omit it if it causes confusion.





int main(string[] argv)
{

//auto ps = ComPtr!_Application(CLSID_PS).require;

	//const auto CLSID_PS = 
Guid!("6DECC242-87EF-11cf-86B4-44455354"); // PS 90.1 fails 
because of interface issue
	const auto CLSID_PS = 
Guid!("c09f153e-dff7-4eff-a570-af82c1a5a2a8");   // PS 90.0 
works.





auto hr = CoInitialize(null);
auto iid = IID__Application;


_Application* pUnk;

hr = CoCreateInstance(_PS, null, CLSCTX_ALL, , 
cast(void**));

if (FAILED(hr))
throw new Exception("ASDF");

}

The photoshop.d file
http://www.filedropper.com/photoshop_1


So, I guess it works but how to access the methods? The 
photoshop file looks to have them listed but they are all 
commented out.


They're commented out because Photoshop seems to have only 
provided a late-binding interface and you have to call them by 
name through IDispatch.Invoke. It's possible to wrap all that in 
normal D methods, and I'm working on it, but it won't be ready 
for a while.




Re: Accessing COM Objects

2016-06-15 Thread Joerg Joergonson via Digitalmars-d-learn

On Wednesday, 15 June 2016 at 06:09:33 UTC, thedeemon wrote:

On Monday, 13 June 2016 at 17:38:41 UTC, Incognito wrote:


[...]


There are ready tools idl2d:
https://github.com/dlang/visuald/tree/master/c2d

[...]


I can't seem to get ComPtr to work.


auto ps = ComPtr!_Application(CLSID_PS).require;

Where CLSID_PS is the Guid from the registry that seems to work 
with CoCreate. _Application was generated from tbl2d.



See my other post for a more(not much) complete description of 
the issues files.






Re: Accessing COM Objects

2016-06-15 Thread Joerg Joergonson via Digitalmars-d-learn

On Wednesday, 15 June 2016 at 17:20:31 UTC, John wrote:
On Wednesday, 15 June 2016 at 16:45:39 UTC, Joerg Joergonson 
wrote:
Thanks. When I ran it I got a d file! when I tried to use that 
d file I get undefined IID and IDispatch. I imagine these 
interfaces come from somewhere, probably built in?


Any ideas?


Add the following after the module name:

  import core.sys.windows.com, core.sys.windows.oaidl;


Thanks. Should these not be added to the generated file?

Also, could you add to it the following:

const static GUID iid = 
Guid!("5DE90358-4D0B-4FA1-BA3E-C91BBA863F32");


inside the interface (Replace the string with the correct guid)?



This allows it to work with ComPtr which looks for the iid inside 
the interface, shouldn't hurt anything.


In any case, I haven't got ComPtr to work so...


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);
}




also tried CoCreateInstance and getting error 80040154

Not sure if it works.



Changed the GUID to another one found in the registry(not the one 
at the top of the generated file) and it works. Both load 
photoshop



int main(string[] argv)
{

//auto ps = ComPtr!_Application(CLSID_PS).require;

	//const auto CLSID_PS = 
Guid!("6DECC242-87EF-11cf-86B4-44455354"); // PS 90.1 fails 
because of interface issue
	const auto CLSID_PS = 
Guid!("c09f153e-dff7-4eff-a570-af82c1a5a2a8");   // PS 90.0 works.





auto hr = CoInitialize(null);
auto iid = IID__Application;


_Application* pUnk;

hr = CoCreateInstance(_PS, null, CLSCTX_ALL, , 
cast(void**));

if (FAILED(hr))
throw new Exception("ASDF");

}

The photoshop.d file
http://www.filedropper.com/photoshop_1


So, I guess it works but how to access the methods? The photoshop 
file looks to have them listed but they are all commented out.


I suppose this is what ComPtr and other methods are used to help 
create the interface but none seem to work.









Re: Accessing COM Objects

2016-06-15 Thread John via Digitalmars-d-learn
On Wednesday, 15 June 2016 at 16:45:39 UTC, Joerg Joergonson 
wrote:
Thanks. When I ran it I got a d file! when I tried to use that 
d file I get undefined IID and IDispatch. I imagine these 
interfaces come from somewhere, probably built in?


Any ideas?


Add the following after the module name:

  import core.sys.windows.com, core.sys.windows.oaidl;


Re: Accessing COM Objects

2016-06-15 Thread Joerg Joergonson via Digitalmars-d-learn

On Wednesday, 15 June 2016 at 15:12:06 UTC, thedeemon wrote:
On Wednesday, 15 June 2016 at 07:01:30 UTC, Joerg Joergonson 
wrote:



It  seems idl2d from VD is not easily compilable?


I don't remember problems with that, anyway here's the binary I 
used:

http://stuff.thedeemon.com/idl2d.exe


It crashes when I use it ;/

core.exception.UnicodeException@src\rt\util\utf.d(290): invalid 
UTF-8 sequence


tbl2d did work and gave me a d file but I need to figure out what 
IID and IDispatch are.




Re: Accessing COM Objects

2016-06-15 Thread Joerg Joergonson via Digitalmars-d-learn

On Wednesday, 15 June 2016 at 08:24:41 UTC, John wrote:

On Wednesday, 15 June 2016 at 08:21:06 UTC, John wrote:
OK, adding the return type to the signature should fix that. 
So:


  private static Parameter getParameters(MethodImpl method)


Sorry, I meant the getParameter methods should return be:

  private static Parameter[] getParameters(MethodImpl method)

and

  private static Parameter[] getParameters(MethodImpl method, 
out Parameter returnParameter, bool getReturnParameter)


Thanks. When I ran it I got a d file! when I tried to use that d 
file I get undefined IID and IDispatch. I imagine these 
interfaces come from somewhere, probably built in?


Any ideas?


Re: Accessing COM Objects

2016-06-15 Thread Joerg Joergonson via Digitalmars-d-learn

On Wednesday, 15 June 2016 at 16:03:04 UTC, Jesse Phillips wrote:

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

[...]


There is also:
https://github.com/JesseKPhillips/Juno-Windows-Class-Library

It kind of provides similar highlevel options as the "Modern 
COM Programming in D."


But I don't use it and have only be somewhat keeping it alive 
(I had some hiccups in supporting 64bit), so I haven't been 
working to improve the simplicity of interfacing to COM objects.


It also includes definitions for accessing Windows COM objects 
which aren't needed when interfacing with your own or other COM 
objects. I'd like to have two libraries, Juno Library and Juno 
Windows Class Library.


I'll check it it out...


Re: Accessing COM Objects

2016-06-15 Thread Jesse Phillips via Digitalmars-d-learn

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


There is also:
https://github.com/JesseKPhillips/Juno-Windows-Class-Library

It kind of provides similar highlevel options as the "Modern COM 
Programming in D."


But I don't use it and have only be somewhat keeping it alive (I 
had some hiccups in supporting 64bit), so I haven't been working 
to improve the simplicity of interfacing to COM objects.


It also includes definitions for accessing Windows COM objects 
which aren't needed when interfacing with your own or other COM 
objects. I'd like to have two libraries, Juno Library and Juno 
Windows Class Library.


Re: Accessing COM Objects

2016-06-15 Thread thedeemon via Digitalmars-d-learn
On Wednesday, 15 June 2016 at 07:01:30 UTC, Joerg Joergonson 
wrote:



It  seems idl2d from VD is not easily compilable?


I don't remember problems with that, anyway here's the binary I 
used:

http://stuff.thedeemon.com/idl2d.exe



Re: Accessing COM Objects

2016-06-15 Thread John via Digitalmars-d-learn

On Wednesday, 15 June 2016 at 08:21:06 UTC, John wrote:

OK, adding the return type to the signature should fix that. So:

  private static Parameter getParameters(MethodImpl method)


Sorry, I meant the getParameter methods should return be:

  private static Parameter[] getParameters(MethodImpl method)

and

  private static Parameter[] getParameters(MethodImpl method, out 
Parameter returnParameter, bool getReturnParameter)




Re: Accessing COM Objects

2016-06-15 Thread John via Digitalmars-d-learn
On Wednesday, 15 June 2016 at 06:56:59 UTC, Joerg Joergonson 
wrote:

When I try to compile your code I get the following errors:

main.d(953): Error: function 
core.sys.windows.objbase.CoTaskMemAlloc (uint) is not callable 
using argument types (immutable(ulong))

main.d(970): Error: can only slice tuple types, not _error_
main.d(974): Error: can only slice tuple types, not _error_

coTaskMemAlloc is defined with ULONG in the objbase.d file... 
so I have no idea what's going on there.


immutable bufferSize = (funcDesc.cParams + 1) * 
(wchar*).sizeof;

auto names = cast(wchar**)CoTaskMemAlloc(bufferSize);


Looks like bufferSize just needs to be cast to uint. Didn't get 
that error in DMD.




The other two I also don't know:

params ~= new Parameter(method, (name[0 .. 
SysStringLen(name)]).toUTF8(),


If I run it in ldc I get the error

Error: forward reference to inferred return type of function 
call 'getParameters'		


  private static getParameters(MethodImpl method) {
Parameter dummy;
return getParameters(method, dummy, false);
  }

It does compile in DMD though.


OK, adding the return type to the signature should fix that. So:

  private static Parameter getParameters(MethodImpl method)



When running I get the error

 Error loading type library/DLL.

The IDL file is in the same directory


Did you try to pass it an IDL file? No wonder it didn't work - 
you pass in the type library instead, which is a binary file such 
as a DLL, EXE or TLB file. You can get the file's path from 
OleView by highlighting the library on the left (eg Photoshop) 
and on the right it will show a tree with the path beside "win32".


Re: Accessing COM Objects

2016-06-15 Thread Joerg Joergonson via Digitalmars-d-learn

On Wednesday, 15 June 2016 at 06:09:33 UTC, thedeemon 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?


There are ready tools idl2d:
https://github.com/dlang/visuald/tree/master/c2d

and tlb2idl:
https://github.com/dlang/visuald/tree/master/tools

I've used this idl2d and it works pretty well (although not 
perfect, sometimes manual editing still required).


Example of real-world DirectShow interfaces translated:
https://gist.github.com/thedeemon/46748f91afdbcf339f55da9b355a6b56

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


If you have the interface defined AND you know its IID, you can 
request it from CoCreateInstance and then use as ordinary D 
object.


You might want to look at this wrapper that takes most of COM 
machinery:

https://gist.github.com/thedeemon/3c2989b76004fafe9aa0

Then you just write almost as in C#, something like

  auto pGraph = ComPtr!IGraphBuilder(CLSID_FilterGraph, 
"pGraph").require;


  ComPtr!ICaptureGraphBuilder2 pBuilder = 
ComPtr!ICaptureGraphBuilder2(CLSID_CaptureGraphBuilder2).require;

  pBuilder.SetFiltergraph(pGraph);
  ...
  auto CLSID_NullRenderer = 
Guid!("C1F400A4-3F08-11D3-9F0B-006008039E37"); //qedit.dll
  auto pNullRendr = ComPtr!IBaseFilter(CLSID_NullRenderer, 
"nulrend");

  pGraph.AddFilter(pNullRendr, "Null Renderer"w.ptr);
  ...
  auto imf = ComPtr!IMediaFilter(pGraph);
  imf.SetSyncSource(null);

All the CreateInstance, QueryInterface, AddRef/Release etc. is 
taken care of. And even HRESULT return codes are automatically 
checked.


Thanks, if I can get the idl converted I'll test it out. It seems 
idl2d from VD is not easily compilable?




Re: Accessing COM Objects P3

2016-06-15 Thread Joerg Joergonson via Digitalmars-d-learn

[in] long index,
[out] long* value);
[id(0x60020017)]
HRESULT PutClass([in] long value);
[id(0x60020018)]
HRESULT GetGlobalClass(
[in] long index,
[out] long* value);
[id(0x60020019)]
HRESULT PutGlobalClass([in] long value);
[id(0x6002001a)]
HRESULT GetPath(
[in] long index,
[out] BSTR* pathString);
[id(0x6002001b)]
HRESULT PutPath([in] BSTR pathString);
[id(0x6002001c)]
HRESULT GetDataLength(
[in] long index,
[out] long* value);
[id(0x6002001d)]
HRESULT GetData(
[in] long index,
[out] BSTR* value);
[id(0x6002001e)]
HRESULT PutData(
[in] long length,
[in] BSTR value);
};

[
  odl,
  uuid(7CA9DE40-9EB3-11D1-B033-00C04FD7EC47),
  helpstring("Container class for actions system 
parameters."),

  dual,
  oleautomation
]
interface IActionDescriptor : IDispatch {
[id(0x6002)]
HRESULT GetType(
[in] long key,
[out] long* type);
[id(0x60020001)]
HRESULT GetKey(
[in] long index,
[out] long* key);
[id(0x60020002)]
HRESULT HasKey(
[in] long key,
[out] long* HasKey);
[id(0x60020003)]
HRESULT GetCount([out] long* count);
[id(0x60020004)]
HRESULT IsEqual(
[in] IActionDescriptor* otherDesc,
[out] long* IsEqual);
[id(0x60020005)]
HRESULT Erase([in] long key);
[id(0x60020006)]
HRESULT Clear();
[id(0x60020007)]
HRESULT GetInteger(
[in] long key,
[out] long* retval);
[id(0x60020008)]
HRESULT PutInteger(
[in] long key,
[in] long value);
[id(0x60020009)]
HRESULT GetDouble(
[in] long key,
[out] double* retval);
[id(0x6002000a)]
HRESULT PutDouble(
[in] long key,
[in] double value);
[id(0x6002000b)]
HRESULT GetUnitDouble(
[in] long key,
[out] long* unitID,
[out] double* retval);
[id(0x6002000c)]
HRESULT PutUnitDouble(
[in] long key,
[in] long unitID,
[in] double value);
[id(0x6002000d)]
HRESULT GetString(
[in] long key,
[out] BSTR* retval);
[id(0x6002000e)]
HRESULT PutString(
[in] long key,
[in] BSTR value);
[id(0x6002000f)]
HRESULT GetBoolean(
[in] long key,
[out] long* retval);
[id(0x60020010)]
HRESULT PutBoolean(
[in] long key,
[in] long value);
[id(0x60020011)]
HRESULT GetList(
[in] long key,
[out] IActionList** list);
[id(0x60020012)]
HRESULT PutList(
[in] long key,
[in] IActionList* list);
[id(0x60020013)]
HRESULT GetObject(
[in] long key,
[out] long* classID,
[out] IActionDescriptor** retval);
[id(0x60020014)]
HRESULT PutObject(
[in] long key,
[in] long classID,
[in] IActionDescriptor* value);
[id(0x60020015)]
HRESULT GetGlobalObject(
[in] long key,
[out] long* classID,
[out] IActionDescriptor** retval);
[id(0x60020016)]
HRESULT PutGlobalObject(
[in] long key,
[in] long classID,
[in] IActionDescriptor* value);
[id(0x60020017)]
HRESULT GetEnumerated(
[in] long key,
[out] long* enumType,
[out] long* value);
[id(0x60020018)]
HRESULT PutEnumerated(
[in] long key,
[in] long enumType,
[in] long value);
[id(0x60020019)]
HRESULT GetReference(
[in] long key,
[out] IActionReference** reference);

Re: Accessing COM Objects

2016-06-15 Thread thedeemon via Digitalmars-d-learn

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?


There are ready tools idl2d:
https://github.com/dlang/visuald/tree/master/c2d

and tlb2idl:
https://github.com/dlang/visuald/tree/master/tools

I've used this idl2d and it works pretty well (although not 
perfect, sometimes manual editing still required).


Example of real-world DirectShow interfaces translated:
https://gist.github.com/thedeemon/46748f91afdbcf339f55da9b355a6b56

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


If you have the interface defined AND you know its IID, you can 
request it from CoCreateInstance and then use as ordinary D 
object.


You might want to look at this wrapper that takes most of COM 
machinery:

https://gist.github.com/thedeemon/3c2989b76004fafe9aa0

Then you just write almost as in C#, something like

  auto pGraph = ComPtr!IGraphBuilder(CLSID_FilterGraph, 
"pGraph").require;


  ComPtr!ICaptureGraphBuilder2 pBuilder = 
ComPtr!ICaptureGraphBuilder2(CLSID_CaptureGraphBuilder2).require;

  pBuilder.SetFiltergraph(pGraph);
  ...
  auto CLSID_NullRenderer = 
Guid!("C1F400A4-3F08-11D3-9F0B-006008039E37"); //qedit.dll
  auto pNullRendr = ComPtr!IBaseFilter(CLSID_NullRenderer, 
"nulrend");

  pGraph.AddFilter(pNullRendr, "Null Renderer"w.ptr);
  ...
  auto imf = ComPtr!IMediaFilter(pGraph);
  imf.SetSyncSource(null);

All the CreateInstance, QueryInterface, AddRef/Release etc. is 
taken care of. And even HRESULT return codes are automatically 
checked.


Re: Accessing COM Objects

2016-06-14 Thread John via Digitalmars-d-learn

On Monday, 13 June 2016 at 19:26:08 UTC, Incognito wrote:

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.


It's up: https://github.com/jsatellite/tlb2d/tree/master/src/tlb2d

There's probably a few bugs, and type libraries have a tendency 
to re-define existing types so you'll have to comment those out. 
Also it doesn't generate dependencies, but it does list them at 
the top of the generated module so you can run the tool on those 
type libraries manually.


Re: Accessing COM Objects

2016-06-14 Thread Kagamin via Digitalmars-d-learn

Visual D has a tool to convert IDL files to D.


Re: Accessing COM Objects

2016-06-13 Thread Incognito via Digitalmars-d-learn

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.







Re: Accessing COM Objects

2016-06-13 Thread John via Digitalmars-d-learn

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.


Re: Accessing COM Objects

2016-06-13 Thread Incognito via Digitalmars-d-learn

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-44455354}


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

auto iid = IID_IUnknown;

void* pUnk;
	auto hr = CoCreateInstance(_DOMDocument60, null, 
CLSCTX_ALL, , );

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?




Re: Accessing COM Objects

2016-06-13 Thread John via Digitalmars-d-learn

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-44455354}


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

auto iid = IID_IUnknown;

void* pUnk;
	auto hr = CoCreateInstance(_DOMDocument60, null, 
CLSCTX_ALL, , );

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.


Re: Accessing COM Objects

2016-06-12 Thread Mike Parker via Digitalmars-d-learn

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(_DOMDocument60, null, 
CLSCTX_ALL, , (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.


Re: Accessing COM Objects

2016-06-12 Thread Mike Parker via Digitalmars-d-learn

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



Re: Accessing COM Objects

2016-06-12 Thread Incognito via Digitalmars-d-learn

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?





Re: Accessing COM Objects

2016-06-12 Thread Mike Parker via Digitalmars-d-learn

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


Accessing COM Objects

2016-06-12 Thread Incognito via Digitalmars-d-learn
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-44455354}


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

auto iid = IID_IUnknown;

void* pUnk;
	auto hr = CoCreateInstance(_DOMDocument60, null, 
CLSCTX_ALL, , );

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.