D言語 Part34©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
Dでcomのclientを書こうとして付属のサンプルソースを試したら動作しました
wshサーバーをdispatchしてEcho('hoge')みたいなポップアップを出したいのですが
サンプルをどのように書き直せばよいのですか 途中まで書いたコードです
extern (Windows) HRESULT CLSIDFromProgID(const wchar *, CLSID *);
const string wsh = "WScript.Shell";
interface IWSH : IUnknown {
extern (Windows) int Echo();
}
DWORD dwVer = CoBuildVersion();
HRESULT hr = CoInitialize(null);
hr = CLSIDFromProgID(wsh.toUTF16z(), &clsid);
IWSH pIWSH;
hr = CoCreateInstance(&clsid, null, CLSCTX_ALL, &IID_IUnknown, &pIWSH);
// FAILED(hr)の判定コードは省略していますがここまでは動作しているようです
// pIWSHに値は入っているようですが次の場所でAccessViolationします
pIWSH.Echo();
CoUninitialize();
pIWSH.Echo(); の行をコメントアウトすると何も起きませんが正常に完了します
あと
&IID_IUnknown
のところを
&IID_IDispatch
に書き換えてもだめでした >>294
ちょっとまだよく分かってなくてEcho呼んでも何も起きなかったけど、
PopUp呼べたので参考になりますか?
http://dpaste.dzfl.pl/15f1655e540e >>294
IDLとかタイプライブラリとか見ずに静的バインディングしようとしてる
普通は中間ヘッダを入手するかツールで生成する
C++で一度やったことがないとダメ
ちなみに >>295 は動的バインディング >>294
WScript.Shell に Echo は無いよw >>297
うっかり勘違いしてました
標準のinterfaceから継承する方法ですが
interface IWSH : IUnknown { // add vtbl to define as IDispatch
extern (Windows) HRESULT GetTypeInfoCount(UINT *);
extern (Windows) HRESULT GetTypeInfo(UINT, LCID, REFIID);
extern (Windows) HRESULT GetIDsOfNames(REFIID, LPOLESTR *, UINT, LCID, DISPID *);
extern (Windows) HRESULT Invoke(DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *);
}
にして
hr = CoCreateInstance(&clsid, null, CLSCTX_ALL, &IID_IDispatch, &pIWSH);
したら
後は >>295 さんと同じように PopUp("Hage") を Invoke 出来ました
ほんとうにありがとうございました 質問です。
SysTime st = Clock.currTime();
writefln("%s", st.toISOExtString());
writefln("%s", st.toISOString());
の動作で末尾の小数点以下の数字 (hnsecs) が
7桁になるときと6桁になるときがあるみたいです。
先頭の 0 が表示されないケースがあると思ったのですが
通常の '年月日T114500.1234567' 以外に
'年月日T114500.0123456' は表示されました。
ところがたまに '年月日T114500.123456' と表示されることがあります。
つまり '年月日T114500.0123456' なのか '年月日T114500.1234560' なのか判りません。
hnsecs==0 のときにこのパターンがあるみたいなのですがみなさんのところはどうですか?
DMD32 D Compiler v2.063.2
です。 ちょっと紛らわしいので一部訂正します。
x 小数点以下の数字 (hnsecs) が
o 小数点以下の数字 (total hnsecs) が
x hnsecs==0 のときにこのパターンが
o msecs==123, usecs=456, hnsecs==0 のときにこのパターンが "年月日T114500.123456" == "年月日T114500.1234560"じゃないの? なるほど小数点以下だから末尾の0は除かれるんですね。
7桁だと思って決め打ちしない方が良いですね。 Duration d = hoge - fuga;
d.total!"msecs", d.total!"usecs", d.total!"hnsecs" を使うことにします。 python の __getattr__
ruby の method_missing
javascript の __noSuchMethod__
みたいなものを期待して
D で同じようなものが有るかどうか検索したら
http://forum.dlang.org/post/op.usipp0mij5j59l@my-tomato
というやりとりが見つかりました
そこのサンプルをコンパイルしようとしたのですがエラーになります
D で opDotExp ってどう使うんですか? opDispatch()
ただし型のコントロールは引数とか名前付けとか工夫して自前で面倒を見る必要がある import std.stdio;
class Hoge {
void opDispatch(string s)() { IDispatch で
auto xl = Dispatch("Excel.Application");
xl.Visible = true;
auto workbooks = xl.Workbooks;
まではうまく逝くのに
auto book = workbooks.Add();
で Access Violation してしまう
何が間違ってるんだろう Add がデフォルト引数を持ってるけど引数明示したらどうなるかな
ぐぐったら xlFileFormat 列挙型 とか出てくる a.unknownproperty = hoge;
みたいなのも opDispatch!"unknownproperty"(Args args...) で書けますか? ちょっと違う気がしますが
なんとなく方向性はわかりました さっきから変な現象になりました
windows10 なのですが
import std.stdio;
int main(string[] args)
{
writefln("@");
return 0;
}
だけのファイルを d_opDispatch.d というファイル名で保存して
dmd -run d_opDispatch.d を実行しても何も表示されないので
dmd d_opDispatch.d を実行して出来た d_opDispatch.exe を
cmd.exe から実行すると UAC のポップアップが出ていることがわかりました
そのまま許可すると別の cmd.exe が開かれてその中で @ が出力されています
また d_opDispatch.exe を test.exe に rename したら UAC は出なくなりましたω
それで test_opDispatch.exe にするとまた UAC が出たので
test_op_Dispatch.exe とか op_Dis_patch.exe とか試したのですが
この二つも UAC が出てきますω
また test.exe に戻したら普通に動くようになりました
ソースのときのファイル名は関係ないみたいなので
dmd -oftest.exe -run d_opDispatch.d
でとりあえず解決は出来てるんですけど何なんですかねこれ
windows10 のブラックリストに登録されちゃってるんですか?ω
それともうちだけですか? opDis_patch.exe もだめです
名前変えるだけで動かなくなります orz 実行ファイル名で必要権限が変わるという余計なお世話なアレか Dのenumってどうなってんの?
名前付きだけA.B.Aとかできるのがわけわからん
http://dpaste.dzfl.pl/99ffb64db405 名前付きenumが普通に想像するようなenum
名前なしenumは常時インライン展開されてデータセクションに出力されないconstもどき、じゃなかったっけ
その上で 型.メンバ の形で使えるプロパティは 変数(定数).メンバ の形でも使えるというだけのような気がする >>321
なるほど、(名前付き)enumが型という認識が不足してたのか
それなら各要素自体はprivateじゃないからアクセスもできて当然なのかな
ありがとう auto hoge(T...)(T args){ return args[0] ; }
みたいな関数があるとき
呼び出し側で
auto fuga = hoge();
で呼ばれたか
auto fuga = hoge;
で呼ばれたか
どちらなのかを呼ばれた側で区別出来ますか? たぶん無理
それにその辺りの仕様はふらついているので
今の仕様で組んでも後でダメになる可能性がある call と get と set を実装して dispatch する目論見だったんですが
PyObject だと get と call の区別が微妙なんです DWT(https://github.com/d-widget-toolkit/dwt)を試しているのですが
Drag and Drop のサンプル(snippetxx.d)が全く見つからないので
SWT(http://www.eclipse.org/swt/snippets/#dnd)を取ってきて試すも
cannot cast expression event.data of type object.Object to string
のコンパイルエラー、cast じゃダメなので何がしかの変換が必要らしい
で、DWT の Drag and Drop はこんな感じで
動かしてるよ〜という情報をお持ちの方おしえてくださいませm(_ _)m 2.069.2でDelimited Strings内にASCII以外があると怒られるよぅ
q"EOS
日本語 ← Error: character 0xa5 is not a valid token
EOS" 2.069の文字列処理で日本語入ってるときの挙動が変わって往生した >>324
とりあえず呼び出し側で
auto fuga = hoge.unknownmethodcall([]);
と
auto fuga = hoge.unknownproperty;
で区別することにしたらうまく別けられました
ところが今度は
hoge.unknownproperty = hage;
で代入しようと hoge class 内で
void opDispatch(string propertyname, T)(T arg){
}
と setter を定義したのですが
hoge.unknownmethodcall([]);
の方まで setter に奪われるようになってしまいました getterのopDispatchの戻り値を構造体でラップするとか。
http://dpaste.dzfl.pl/e089dbd99093 ああテンプレートで呼び分けるんじゃなくて
全部まとめて一ヶ所で受けて if で分けるんですね
参考になります
ありがとうございます import std.process;
で pipeProcess とか spawnProcess とか使えるのは判ったのですが
windows で win32api の CreateProcessAsUser とか CreateProcessWithLogonW
に相当することが実行可能なモジュールはありますか? 標準では最低限のAPIしかないので
自分でポーティングするか拾ってくるかしましょう linuxで7zip.soのbindingを書こうとしています。7zipのC++側のIUnknownが
struct IUnknown
{
STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;
STDMETHOD_(ULONG, AddRef)() PURE;
STDMETHOD_(ULONG, Release)() PURE;
#ifndef _WIN32
virtual ~IUnknown() {}
#endif
};
このように宣言されているのですが、Dのinterfaceでデストラクタを宣言できなくて困っています。
超その場しのぎとして、DのIUnknownの宣言のReleaseの後にダミーのメソッドを、
・2個追加することでC++で実装されたinterfaceをDから呼び出すことが、
・1個追加することでDで実装されたinterfaceをC++から呼び出すことが、
それぞれできたのですが、とてもまともな解決策とは思えません。
どうすべきでしょうか。 winじゃなくてlinuxでやりたいみたいよ
一晩寝たら 空のデストラクタなんていらなかったんや
って気づくかもしれない >>337-339 クソして寝ましたが、仮に空(とはいえvirtual)のデストラクタがまるで無意味だったとしても、
bindingの体をとっているのでp7zip側のコードを変えるのはちょっと。
むしろvtblのズレが336程度の単純さならばソレで行くかと。
気になるのはDから呼ぶ場合とC++から呼ぶ場合の非対称性ですが、こういうもんなんですか? C++ネイティブの呼び出しっていつから「ちゃんと」できるようになったんですか?(小声) あ、非対称っていうのは勘違いだったかもごめ。
http://dpaste.dzfl.pl/4e7956f36a47
これで解決や!どうもありがとう!
>>341 WindowsでCOMを使った7zipのbindingはもっとすんなりいきましたよ。 自分のクラス(Fuga)を定義していて string へ変換するときに
Fuga f("hage");
string hoge = f;
みたいな書き方をしたいのですが
どんなメソッドを作っておけば良いのですか? Fuga f = new Fuga("hage");
string hoge = f;
です class Fuga {
private string s_;
this(string s) { s_ = s; }
alias s_ this;
} alias s_ this; とは驚きですが
Fuga f = new Fuga("123");
int i = f;
としたときでも i に 123 が入るようになりますか?
条件後出しですみません ちなみに
Fuga f = new Fuga("123");
string s = f; // なら s = "123"; と同じ
int i = f; // なら i = 123; と同じ
という意味です
これも alias だけで出来てしまうんでしょうか? そういうのはたいてい変数に移して終わりじゃなくて、その先があるでしょ
例えば関数に渡すならその関数をテンプレートでうまくまとめるのが D流
単に出力するだけなら writeln(f) ここを参考に
http://www.kmonos.net/alang/wnd/topics/winapi.ja.html
Win32API を使って drag & drop を実装してみたところ
case WM_DROPFILES: の中で
HDROP dr = cast(HDROP)wp;
TCHAR[] buf = new TCHAR[MAX_PATH];
int l = DragQueryFile(dr, 0, buf.ptr, buf.length);
if(l < buf.length) buf[l] = 0;
string bs = to!string(buf[0..l]);
version(Unicode){
writefln("0: %s", to!string(bs.toMBSz()));
string name = bs;
}else{
writefln("0: %s", bs);
string name = fromMBSz(bs.toStringz());
}
writefln("1: %s", name);
とすると
drag & drop したファイル名が 「森鷗(環境依存文字2)外(環境依存文字3)る.ext」 のとき
最後の name の表示が -version=Unicode したときとしないときで結果が違います
toMBSz と fromMBSz とで不可逆なのは判るのですが
MBSz -> UTF8 するときも結果が違うのは何故でしょうか?
(ただし表示は違うのですが同じファイルが対象になってちゃんと動作します) >>351
Multiple AliasThisを使えば可能
もちろんコンストラクタ内で変換して保持とかする必要はあるけど
……なので実装されるのを楽しみに待っててくれよな! >>353 SHIFT-JISに含まれてない文字だから仕方ないとおもわれ。
DragQueryFileAの方ではかわりに 63(ASCIIのハテナマーク)が送られてきてる。
A付関数のことなんて早く忘れるんだ! string valueOf(){ return s_; }
int valueOf(){ return to!int(s_); }
alias valueOf this; >>356
不思議なのは *A バージョンの方でも正常に動作してるって所なんだよね 上は Utf16->Utf8->SJIS で余計な変換してるからじゃないの >>358
A版の内部処理でことごとく文字化けしてるから
文字化けしたファイル名がマッチするせい >>360
わたしもそう思ったんですが
出来上がった hoge.7z ファイルの中の
ファイル名は文字化けしておらず正常なんです >>361
?が1文字マッチのワイルドカードってのは関係してない? あれ、戻り値だけ違う関数ってオーバーロードできたっけ? 宣言はできるけど使えない
左辺値から型推論とかしてくれると嬉しいんだけどね T valueOf(T)(){ return to!T(s_); }
これもうまくいかんな 明示cast必須になるけど
T opCast(T)(){ return s_.to!T; } alias hoge this; しなくてよくなるからありがたいね Advent Calendar面白かったよ。
書いた人たち乙です。 冬休み中にAdventCalendarゆっくり読む
楽しみだなあ。書いた人たち乙〜。 https://github.com/D-Programming-Language/dlang.org/commit/77324039087e9283f40244195857c2f9fd4712eb#diff-59280080f58c2ff747f066c5b0b2fcebL423
- $(LI As a first programming language - Basic or Java is more suitable
+ $(LI As a first programming language - Python or JavaScript is more suitable
時代の流れを感じる
Basicの方が初めてのプログラミングには良いと思うんだがなぁ まあ妥当と思う。Basicって括りがざっぱだけど、
(N-88とかそういう)BASIC → まあやらんでええやろ。行番号とか。ねえ?
VB → PowerShellが出てシリスボミ感がある。
Python → 個人的にはtkinterの存在がでかい。
JavaScript → すぐ遊べる。すぐ自慢できる(←重要
あとは英才教育的な観点からならプログラミンとか? 時代は Elixir ですよ
D でもいいけど
すぐ自慢できるのは Python だろ std.experimental.yeslolitanotouch 64bitのWin32対応DLL作りたいんだけど? あれ途中で切れた。
dmd -m64 -shared mydll.d dll.d mydll.def >>384 それぞれ書かれた時期が違うんじゃまいか DMD で単純な x64 バイナリを作るところまでは行けてるんでしょ?
Win32 DLL も作れるんでしょ?
x64 で Win32 App と結合できるかって話でしょ?
出来ないと思うけど ブリッジ役のDLLも用意して64<-->32間をプロセス間通信でうんたらかんたら >>336
> DのIUnknownの宣言のReleaseの後にダミーのメソッドを、
> ・2個追加することでC++で実装されたinterfaceをDから呼び出すことが、
> ・1個追加することでDで実装されたinterfaceをC++から呼び出すことが、
> それぞれできたのですが、とてもまともな解決策とは思えません。
https://issues.dlang.org/show_bug.cgi?id=15589#comment_text_0
やっぱりダミーを追加するしかないらしい わぁ!どうもありがとう!まだ書きかけ&お粗末ですが、その時の成果物です。
https://github.com/garlic-flavor/D7z
ツッコミ/プルリクお待ちしております。m(_ _)m いつのまにか公式が改装してた
なんかすごくプログラミング言語の公式ページっぽい /r/programming 見てるとほぼ毎日Dの記事があって、ついに時代がきたか感がある ■ このスレッドは過去ログ倉庫に格納されています