最近开发一个程序,需要从c++端启动一个c#开发的程序,并传递参数。
具体做法是:在c++端调用CreateProcess()来启动c#端,并传递相关参数,而在c#端通过Main(string[] args)中的args来接收命令行参数。
C++发送端代码:
int main(int argc, char* argv[])
{
char *fileName="c:\csharp.exe";
char *params="参数1 参数2 参数3";//传递三个参数
PROCESS_INFORMATION pii;
STARTUPINFO sii;
memset(&sii,0,sizeof(sii));
sii.cb=sizeof(sii);
sii.wShowWindow=SW_SHOW;
sii.dwFlags=STARTF_USESHOWWINDOW;
CreateProcess(fileName, params,NULL,false,NULL,NULL,NULL,NULL,&sii,&pii);
return 0;
}
c#接收端代码:
static void Main(string[] args)
{
string msg = "";
if (args.Length > 0)
{
Console.WriteLine("参数个数:" + args.Length);
for (int i = 0; i < args.Length; i++)
{
msg = args[i];
Console.WriteLine("参数" + i + ":" + msg);
}
}
else
{
Console.WriteLine("没有获取命令行参数");
}
Console.ReadKey();
}
结果如下:
如果将c++中的params 改为:
char * params =" ";//传递0个参数
或
char *params="参数1";//传递1个参数
如果将c++中的params 改为:
char *params="参数1 参数2";//传递2个参数
分析:在csharp端接收的参数比vc端发送的参数少一个,即vc端发送的第一个参数在csharp端没有接收到。
看到这个结果,我觉得很有趣,我想反过来如果从csharp端发送vc端接收结果会怎么样呢?
CSharp发送端:
Process p = new Process();
p.StartInfo.FileName = " c:\VC.exe"; //程序名
p.StartInfo.Arguments = "参数1 参数2 参数3"; //程式执行参数
p.Start(); //启动
C++接收端:
int main(int argc, char* argv[])
{
if (argc>0)
{
cout<<"参数个数是"<<argc<<endl;
for (int i=0;i<argc;i++)
{
char * msg=argv[i];
cout<<"参数"<<i<<": "<<msg<<endl;
}
}
else
cout<<"没有获取命令行参数"<<endl;
char ii;
cin>>ii;
return 0;
}
执行结果:
分析:在csharp端明明只发送了三个参数"参数1 参数2 参数3",但在C++接收端却接收了四个参数,而且第一个参数是vc端程序的名称。
究其原因,原来,c/c++的入口函数main(int argc, char* argv[])和c#入口函数main(string[] argv)的区别。c/c++会将程序名称作为第一个参数接收,而c#不会。如下:
VC端:
int main(int argc, char* argv[])
{
if (argc>0)
{
cout<<"参数个数是"<<argc<<endl;
for (int i=0;i<argc;i++)
{
char * msg=argv[i];
cout<<"参数"<<i<<": "<<msg<<endl;
}
}
else
cout<<"没有获取命令行参数"<<endl;
return 0;
}
运行:c:\vc.exe 1 2 3
结果:
分析:命令行中一个有四个参数“c:\vc.exe” “1” “2” “3”,第一个“c:\vc.exe”是程序名称,其他三个“1” “2” “3”才是真正的参数,但结果将四个参数都接收并显示了,可见, C++将程序名称视为第一个命令行实参。
CSharp端:
static void Main(string[] args)
{
string msg = "";
if (args.Length > 0)
{
Console.WriteLine("参数个数:" + args.Length);
for (int i = 0; i < args.Length; i++)
{
msg = args[i];
Console.WriteLine("参数" + i + ":" + msg);
}
}
else
{
Console.WriteLine("没有获取命令行参数");
}
Console.ReadKey();
}
运行:c:\csharp.exe 1 2 3
结果:
分析:命令行中一个有四个参数“c:\ csharp.exe” “1” “2” “3”,第一个“c:\ csharp.exe”是程序名称,其他三个才是真正的参数。但运行结果没有显示程序名称,可见,与C++ 不同,在 C# 中不将程序名称视为第一个命令行实参。
所以,在从c/c++向c#传递命令行参数时(使用CreateProcess来调用C#程序),一定要在这些参数前添加一个无用的参数。例如,c#要接受的参数是“1 2 3”,那么在c/c++端的命令行参数是“*** 1 2 3”。相反的,从c#向c/c++传递命令行参数时,c/c++接收的参数应该从第二个算起,因为第一个参数是程序的名称。