プログラマーの憂鬱。
こんだけ書けば少しは気が晴れるかなぁ。。。
2016.09.24
c# .Net4で.Net2のDLLを動かす呪文。
useLegacyV2RuntimeActivationPolicy 属性を true に設定する必要があります。
プロジェクト/ソリューションエクスプローラー/app.config
//-------------------------------------------------------------------------------------------------------------------------------------- <?xml version="1.0"?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> </startup> </configuration> //--------------------------------------------------------------------------------------------------------------------------------------
WFPのスタートアップとクロージング
ContentRederedとClosingはウィンドウメッセージのプロパティからハンドリングする
https://msdn.microsoft.com/ja-jp/library/ms748948(v=vs.110).aspxwfpなのかwpfなのか未だにコンガラカル
2015.08.30
【c#からc++のDLLを呼び出すときの注意点】
.Net4以降から変わったそうですが巷のサンプルはそれ以前のものが多く
何をやってもエラーになるという。これじゃ使えないと思いながらも
しかし、他の方は問題なく使っているという。何が問題なのか調べているうちに
ようやく判明。
でもって、DLLの呼び出しなんて滅多にやらないから、いざという時にまたぐぐる件をどうにかしたいという訳で
c#(.Net4以降)からc++などのDLLを呼び出す時の呪文をここに書いときます。
[DllImport("Hoge.dll", CallingConvention = CallingConvention.Cdecl)]
ここの"CallingConvention = CallingConvention.Cdecl"が必要。
ついでにサンプル
//c#側
//using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
private struct STPart {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] c1;
[MarshalAs(UnmanagedType.I4)]
public int iStat;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public long [] dwArray;
};
[StructLayout(LayoutKind.Sequential)]
struct STMain {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public STPart[] stPart;
}
[DllImport("cs2CppDLL.dll", EntryPoint = "foo2", CallingConvention = CallingConvention.Cdecl)]
static extern int foo2(ref STMain a);
private void button1_Click(object sender, EventArgs e) {
STMain stm = new STMain();
stm = new STMain();
stm.stPart = new STPart[10];
for (int i = 0; i < 10; ++i) {
stm.stPart[i] = new STPart();
stm.stPart[i].c1 = new byte[10];
stm.stPart[i].dwArray = new long[16];
}
foo2(ref stm);
string sRet = "";
for (int lp = 0; lp < 10; ++lp) {
for (int i = 0; i < 10; ++i) {
sRet = i.ToString() + "=" + stm.stPart[lp].c1[i].ToString();
listBox1.Items.Add(sRet);
}
sRet = "stat=" + stm.stPart[lp].iStat.ToString();
listBox1.Items.Add(sRet);
for (int i = 0; i < 16; ++i) {
sRet = "dwArray" + i.ToString() + "=" + stm.stPart[lp].dwArray[i].ToString();
listBox1.Items.Add(sRet);
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//DLL側
typedef struct {
char c1[10];
int stat;
__int64 dwArray[16];
} STPart;
typedef struct {
STPart sPart[10];
} STMain;
extern "C" {
__declspec(dllexport) int foo2(STMain *);
}
int foo2(STMain *sCPP)
{
int ret=0;
for(int lp=0;lp<10;++lp){
for(int i=0;i<10;++i){
sCPP->sPart[lp].c1[i] = i+1 + (lp*100);
}
sCPP->sPart[lp].stat=1+(lp*100);
for(int i=0;i<16;++i){
sCPP->sPart[lp].dwArray[i] = (double)i+(double)(lp*100);
}
}
return(ret);
}
//////////////////////////////////////////////////////////////////////////////////////////
sampleプロジェクトのDL
DLLのコンパイル後処理でコピーしてますんで、そこはご使用の環境に合わせてください。
※ご利用にあたっては自己責任でお願いします。
/*****************************************************************************************/
2013/09/24 SKソフト納期遅れ0.5ヶ月。
なんていうかド素人にPCの知識が少しある程度の社長さんなんだね。。。ソフトハウスなのに。。。
そんな人が現地に行ってベータソフトインストしてデモンストレーション&本番なんて怖いわあぁ。。。
で、案の定・・・
現地導入時に仕様変更。。。やめてけろー!!
プログラマーの常識が通用しない
例えばフォントサイズを全部大きくしてくれとか。。。画面全部設計し直し。どれだけ大変なのかと。。。
ボタンやスタティックテキストだけならまだしも、コンボボックスとかリストボックスとかどうすればいいの?ハミでないのかね?
もうね、その時だけ解像度低くしてしまおうかと。。。でもタクスバーまでデカくなっちまうな(w
思い付きで仕様を変えようとする。。。だから、それは、仕様書ではこうなってるでしょ?と。。。え?俺様が仕様書?
仕様書に書いてある事を否定して指導される。。。しかも2度。。。また言ってるよこの人。。。若年性痴ほう症かと。。。
1度目はご自分で作った仕様書にこう書いてあって、そうするとこうなります。と言ったが、2度目はさすがに何も言えなかった。
仕様書ではオートナンバーでは入力できないコードが入る。にもかかわらず、「コードはオートナンバーと同じだ」と否定される。
いやそれだめでしょ?3番目にコード「999のその他」って入れられないじゃない998まで空欄つくるとか?えぇぇぇぇぇ???
XPとW7をサポートしろとか。しかもオフラインであってもとか。。。xpって来年サポート終了するんですよ?
.NET やSPなんて入れられないじゃないの???だってそれやっちゃうと、1台だけセキュリティレベル上がって
Lanでつながってる他のPCと接続できなくなるよね?なかにはウィルスに感染したプログラムがあって、それ
隔離されちゃったら動かないソフトもあるかもですよね?これってアップデートしたあと元に戻せるの?
ウェブのリンクを指定してDLしてくれって書いたのに違うものDLしてインストしようとしてるし。。。
送ってもらったドライバーは違うメーカーのものだし。。。
途中で仕様が膨大に膨らむ。。。それ一人で何か月かかるかと。。。最初にお話しした通り、自分は他にも仕事してるんですが???
導入直前で一部完成させるのに5日間一時間〜2時間の睡眠、しまいには3日連続哲也。運転中に何度睡魔に襲われた事か。。。
で、休憩中に30分寝過ごしてヤバイ事になったのは内緒だ。遅延理由は工事で渋滞にしといた。(ぉ
哲也3日目は頭痛がしたな。歳は言いたくないけど老眼が入ってきてねぇ、目が瞼で塞がって見えないしぃ。乱視も少しあるしぃ。。。
コーディングなんてカンでやってますよぉ??? 犬の散歩も棚上げですうぅぅ。
RS232-cで通信してるのに。モニターないんですか。で、通信がおかしいと???それってカンですか?
この仕事終わったらやめるかなぁ。。。
2013/03/04 デモソフト作成@50K
2013/02/?? 某ソフトハウスの外注サンデープログラマーとして口頭にて契約?
平日は運転手の仕事があるので実質できるのは日月金の3日。
※後日日曜のみに変更。さらに そのあと日月金に戻る。
※内容は少し盛ってます(ぉ
2015/04/25
お久しぶりです。
ここ最近c#でごにょごにょやってる五莉でございます。
実はそれ以前にc++で作成してしまったプログラムが30本近くあったのです。
日程と予算の都合でc#に移行できないため、部分的にc#の処理をDLLにしてc++から利用する事に。
当初、c#のDLLをCOM登録してActiveX的な利用を考えたけど、クライアントが地方にあったりして。
DLLのアップデートに伴うCOMの再設定が煩わしいんです。できるオペレータもいないし。。。
という事で、c++からcliのDLLを呼んでそのDLLがc#のライブラリDLLを呼ぶというテスト。
#文字列が正しく取れれば大丈夫だろうという考えですが、、、
まぁ、これなら行けるかな?
バグってる?。。。いやいや、「ちわんこ〜」で合ってんです(w
え?
五莉<オマエノアタマガ…
まぁ、多少なりに( ゚∀゚)アハハ八八ノヽノヽノ \ / \
#プログラムはエラー処理とかしてませんのですみません。
#かなりバギーです。
#あくまで自分のための備忘録という事で、あしからず。
#ご利用は自己責任でお願いします。
//c#のライブラリ部分
namespace CSLib {
public class CsClasslib {
//C:ドライブrootにファイル作ります
private string filename=@"c:\test.txt";
private string strPool="";
public int csGetStr(ref string str)
{
if(0<strPool.Length)
{
str=strPool;
}else{
str = "CsClassのstringは未設定です";
}
return(0);
}
public int csGetInt()
{
return(22);
}
public int csPutStr(string str)
{
strPool ="CsClassにコピーしてFILEに書いた文字=「"+ str+"」";
FileStream fi=new FileStream(filename,FileMode.Create,FileAccess.Write);
byte[] byAry = Encoding.Unicode.GetBytes(str);
fi.Write(byAry,0,byAry.Length);
fi.Close();
return (0);
}
public int csReadFile(ref string str)
{
int nRet=-1;
if(File.Exists(filename))
{
byte[] byAry =new byte[128];
FileStream fi=new FileStream(filename,FileMode.Open,FileAccess.Read);
int nRead=fi.Read(byAry,0,byAry.Length);
fi.Close();
if(0<nRead)
{
byte[]byTemp=new byte[nRead];
for(int i=0;i<nRead;++i)
{
byTemp[i]=byAry[i];
}
string strRf=System.Text.Encoding.Unicode.GetString(byTemp);
str = "CsClassがFileから読んだ文字=「"+strRf+"」";
}
nRet=0;
}
return (nRet);
}
}
}
//cliのDLL関数
__declspec(dllexport) int ciGetText(wchar_t *p);
__declspec(dllexport) int ciGetInt();
__declspec(dllexport) int ciPutGet(wchar_t *pPut,wchar_t *pGet);
__declspec(dllexport) int ciReadFile(wchar_t *pRead);
//cliの処理
int ciGetText(wchar_t *p)
{
System::String^ sRef;
CsClasslib^ cc=gcnew CsClasslib();
cc->csGetStr(sRef);
delete cc;
int nLength = sRef->Length;
for( int i = 0 ; i < nLength ; i++ )
{
p[i] = sRef[i];
}
return(0);
}
int ciGetInt()
{
CsClasslib^ cc = gcnew CsClasslib();
int ret=cc->csGetInt();
delete cc;
return(ret);
}
int ciPutGet(wchar_t *pPut,wchar_t *pGet)
{
String^ cliStr = gcnew String(pPut);
System::String^ sRef;
CsClasslib^ cc = gcnew CsClasslib();
cc->csPutStr(cliStr);
cc->csGetStr(sRef);
delete cc;
int nLength = sRef->Length;
for( int i = 0 ; i < nLength ; i++ )
{
pGet[i] = sRef[i];
}
return(0);
}
int ciReadFile(wchar_t *pRead)
{
System::String^ sRef;
CsClasslib^ cc = gcnew CsClasslib();
int ret=cc->csReadFile(sRef);
delete cc;
if(0==ret)
{
int nLength = sRef->Length;
for( int i = 0 ; i < nLength ; i++ )
{
pRead[i] = sRef[i];
}
}
return(ret);
}
//プログラム本体
//c++の処理
//ダイアログの[Test]ボタンから起動
void Ccpp2cliDlg::OnBnClickedOk()
{
wchar_t wcs[128];
int val=ciGetInt();
CString str;
str.Format(L"戻り値=%d",val);
CListBox *pl=(CListBox*)GetDlgItem(IDC_LIST1);
pl->AddString(str);
memset(wcs,0,sizeof(wchar_t)*128);
ciGetText(&wcs[0]);
pl->AddString(wcs);
wchar_t *pWstr=L"ちわんこ〜";
memset(wcs,0,sizeof(wchar_t)*128);
ciPutGet(pWstr,&wcs[0]);
pl->AddString(wcs);
memset(wcs,0,sizeof(wchar_t)*128);
if(0==ciReadFile(&wcs[0]))
{
pl->AddString(wcs);
}
}
sampleプロジェクトのDL
なんかgoogle Driveがブレビューエラーになるけど普通無理でしょ?>googleさん
テステスデス
SEO | [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送 | ||