位置情報で子どもの居場所をお知らせ

いつもお世話になっております。

環境
Windows VISTA SP1
Visual Studio 2008

疑問
C(C++)からC#で作られたexeを呼ぶ方法がわかりません。
ret = CreateProcess(NULL,Common_Data->exename,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,
NULL, NULL, &si, &pi);

の様にCreateProcessではexeを呼べません。
(Common_Data->exenameにはGetCurrentDirectory使って
絶対パス指定してます)

おそらくC#でつくったプロジェクトの設定を変えてビルド
する必要があると推測していますが
どうすればいいのかわからないです。

以上 よろしくお願いいたします。

A 回答 (4件)

「CreateProcess error 998 ERROR_NOACCESS」


でぐぐってみたところ、以下のような情報がありました。
http://fujiyoshisyouta.blog72.fc2.com/blog-entry …

STARTUPINFO構造体(si)は、正しく初期化してますか?
特に、si.cbにSTARTUPINFO構造体のサイズが正しく入っていないと、
今回のようなエラーを返却する可能性が高いと思います。

http://itpro.nikkeibp.co.jp/article/COLUMN/20070 …
を参考にしてください。
    • good
    • 0
この回答へのお礼

こんばんは!
具体的な例をあげてくださって本当に助かりました。
初期化をきっちりしないとだめなんですね
今回は私は初期化のタイミングがうまくいっていなかった様で
CreateProcess直前で初期化してexeをよんだら
うまくいきました!

アドバイス参考になりました!本当にありがとうございます!

お礼日時:2009/11/09 22:47

#2です。


si.cbの初期化忘れてました。
    • good
    • 0

exeである以上、CreateProcessで呼べないということはありません。


> ret = CreateProcess(NULL,Common_Data->exename,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,
NULL, NULL, &si, &pi);

単純に
TCHAR cmd[]=_T("~~~~~~~~");
STARTUPINFO si;
memset(&si,0,sizeof(si));
PROCESS_INFORMATION pi;
CreateProcess(NULL,cmd,NULL,NULL,FALSE,0,NLLL,NULL,&si,&pi);
だと、どうなんでしょう。
あと、C#以外のexe、例えばnotepadとかは起動可能なのでしょうか。
純粋にexeを起動するだけのプログラムで試したりはしたのでしょうか。
    • good
    • 0
この回答へのお礼

ありがとうございます。
そのようなテストも大事ですね 勉強になりました。

問題の原因は、初期化のタイミングでした。
私は INITDIALOGの中で初期化を行っていたのですが
これがどうもうまく機能していませんでした。
原因は分かりません^^;規模が大規模なシステムなので・・
(これは原因じゃないとは思いますが・・・)
ボタンを押したらC#のexeを呼ぶ実装をしていたのですが、
そのボタンをおしたときに初期化処理をするように修正したら
無事に呼べました!

ありがとうございました!

お礼日時:2009/11/09 22:45

念のため試してみましたが、普通にCreateProcess()でC#のexeは呼べます。



そのC#プログラムが普通にコマンドプロンプトから起動できるよう
作られているなら、CreateProcess()で起動できると思います。

この回答への補足

ちなみに確認ですが、

「CからC#のexeを呼ぶ」ということです。

C#からC#は問題なく大丈夫だと思います。

補足日時:2009/11/08 22:42
    • good
    • 0
この回答へのお礼

こんばんは
ご回答ありがとうございます。
C#で作ったexeは、cmd(コマンドプロンプト)で呼べます。
GetLastErrorで調べたら
998で 不正なメモリにアクセスしています みたいなエラーの様
です。
そこで、呼ぶPATHをチェックしているのですが、
sprintf_s(Common_Data->IniFilePath,256,"%s\\project\\bin\\Release\\project.exe",Common_Data->CurrentDirectory);

という感じでやっています
念のため、PATHをtxtに吐き出して直接コピペして
アクセスしてみたのですがやはりC#のexeは立ち上がります。

うーん OSとの相性が悪いのかな。。

お礼日時:2009/11/08 22:42

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QVC++から引数付きexeファイルの実行

タイトルの通り、VC++から外部ファイルを実行したいのですがどのような関数を使えばよいのでしょうか?
exeファイルを実行中は親プロセスであるVCのプログラムの方を止めておきたいのです。
出来ればexeファイルは引数付きで実行したいと思いますので、よろしくお願いします。
開発環境はVisualStudio2005です。

Aベストアンサー

#1です。こちらで作成したサンプルです。
呼び出し側
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
intret;
printf("system試験開始\n");
ret = system("C:\\VCSTUDY\\printarg\\Debug\\printarg.exe XXX YYY ZZZ");
if (ret == 0){
printf("system成功\n");
}else{
printf("system失敗\n");
}
return 0;
}
----------------------

呼び出される側(c:\\test.exeに相当)
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
inti;
for (i = 0; i < argc; i++){
printf("ARGV[%d]=%s\n",i,argv[i]);
}
return 0;
}
以下、実行結果です。
コマンドプロンプト画面に下記の文字が出力されます。
------------------------
system試験開始
ARGV[0]=C:\VCSTUDY\printarg\Debug\printarg.exe
ARGV[1]=XXX
ARGV[2]=YYY
ARGV[3]=ZZZ
system成功
Press any key to continue
---------------------------

#1です。こちらで作成したサンプルです。
呼び出し側
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
intret;
printf("system試験開始\n");
ret = system("C:\\VCSTUDY\\printarg\\Debug\\printarg.exe XXX YYY ZZZ");
if (ret == 0){
printf("system成功\n");
}else{
printf("system失敗\n");
}
return 0;
}
----------------------

呼び出される側(c:\\test.exeに相当)
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
inti;
for (i = 0; i < argc; i++){
p...続きを読む

QC++からC#のdllを参照する際、引数内に構造体があった場合の処理

いつもお世話になっております。

http://satoshi.web5.jp/memo/connect_dll.htm

VC++2008のMFCプロジェクトにて、C#のdllの関数を扱いたく、
上記サイトを参考に実装してみました。

上記サイトでも挙げているように、C#dll内の関数の引数が、
整数・文字列の場合は、うまく動作するのですが、
引数に構造体を渡し、dllにて構造体のデータを設定してやる関数にて、
引数の構造体ポインタを、どのように渡してやれば良いのかが
分かりません。

具体的には、
VARIANTARGの配列をnewし(変数pVarg)、
pVargに型と変数をセットして、Invoke関数に渡しますが、
その際の、pVargにセットしてやる型が分かりません。

このような場合は、どうすれば良いのでしょう?
よろしくお願いします。

Aベストアンサー

 こんばんは。補足頂きました。

[StructLayout(LayoutKind.Sequential)]
public struct ADUser
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string account;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string name;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string mail;
}

 ではないでしょうか。念の為にもう一度掲載します。

//C#サイド
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

namespace ClassLibrary1
{
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Class1
{
[StructLayout(LayoutKind.Sequential)]
public struct ADUser
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string account;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string name;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string mail;
}

[MethodImpl(MethodImplOptions.Synchronized)]
public int fun(int intPtr)
{
System.IntPtr ptr = new System.IntPtr(intPtr);
ADUser test = (ADUser)Marshal.PtrToStructure(ptr, typeof(ADUser));
test.account = "123-456-7890";
test.name = "c++ to c# struct pointer";
test.mail = "xxx@abc.def.jp";
Marshal.StructureToPtr(test, ptr, true);
return 0;
}
}
}

//C++サイド
typedef struct ADUSER{
char account[100];
char name[100];
char mail[100];
}ADUser;

int main()
{
::CoInitialize( NULL );

CLSID clsid;
BSTR bstrDLL = _com_util::ConvertStringToBSTR( "ClassLibrary1.Class1" );
HRESULT hResult = ::CLSIDFromProgID(bstrDLL, &clsid);
if(!SUCCEEDED(hResult))
return 0;

IUnknown* pUnk = NULL;
hResult = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnk);
if(!SUCCEEDED(hResult))
return 0;

IDispatch* pDisp = NULL;
hResult = pUnk->QueryInterface( IID_IDispatch, (void**)&pDisp );
if(!SUCCEEDED(hResult))
return 0;

DISPID dispid = 0;
LPOLESTR fun = L"fun";
hResult = pDisp->GetIDsOfNames(IID_NULL, &fun, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
if(!SUCCEEDED(hResult))
return 0;

ADUser test = {0};
DISPPARAMS params = {0};

params.cArgs = 1;
params.cNamedArgs = 0;
params.rgdispidNamedArgs = NULL;

VARIANTARG* pVarg = new VARIANTARG[params.cArgs];
::ZeroMemory(pVarg, sizeof(VARIANTARG) * params.cArgs);

pVarg[0].vt = VT_INT;
pVarg[0].intVal = (int)&test;

params.rgvarg = pVarg;

hResult = pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

::printf("[account : %s][name : %s][mail : %s]\n", test.account, test.name, test.mail);

::CoUninitialize();
::SysFreeString(bstrDLL);
delete []pVarg;

return 0;
}

 こんばんは。補足頂きました。

[StructLayout(LayoutKind.Sequential)]
public struct ADUser
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string account;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string name;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 100)]
public string mail;
}

 ではないでしょうか。念の為にもう一度...続きを読む

Q同じソリューション内の別のプロジェクトのメソッド呼び出し

同じソリューション内の別のプロジェクトのメソッド呼び出し

お世話になっております。
Visual Studio でC#で開発をしております。
初心者です。

同じソリューション内にある別のプロジェクトのメソッドを呼び出す方法は
どの様にしたら宜しいのでしょうか。
下記の様に記述しましたら、
「静的でないフィールド、メソッド、またはプロパティ ~省略~ で、
 オブジェクト参照が必要です」と言うエラーが出てしまいます。
何か根本的に間違っているのかも知れません。

何卒、ご教授頂きたく宜しくお願い致します。

        記

呼び出し側
private void button1_Click(object sender, EventArgs e)

  呼び出し先のプロジェクト名.クラス名.メソッド名();
 }


呼び出される側
namespace プロジェクト名

public class クラス名

   メソッド名()
   {
     処理内容
    }
  }
 }

Aベストアンサー

ソリューション エクスプローラにおいて、呼び出し側のプロジェクト ツリーの「参照設定」を右クリックして、「参照の追加」を実行、ダイアログの「プロジェクト」タブにおいて、呼び出される側のプロジェクトを選択してOKを押してください。
Visual C#のインテリセンスが正常に機能し始めれば設定が成功しています。

なお、参照設定の追加により、参照されるアセンブリは参照するプロジェクトの出力フォルダに自動的にコピーされるようになります。
また、被参照アセンブリのプログラム デバッグ データベース ファイル(.pdb)も自動的にコピーされるので、被参照側のソースにブレークポイントを置いて参照側でデバッグを開始すると、きちんとブレークポイントで停止してくれます。


人気Q&Aランキング