读书人

用C#编译C++原代码,该如何解决

发布时间: 2013-10-12 11:54:02 作者: rapoo

用C#编译C++原代码
现自己在做一项目,要用到PLC串口通信,老板要求按照他的原代码来写串口通信部分。(给有原代码,但是用C++写的)现开始用C#来编译原C++代码,遇到一个问题,现求教。谢谢。
A:
因C++原代码中大量用到指针,所以我编译时想用C#中指针,但遇到这个问题?如下:
C++原代码:

BOOL  CDGX::WriteBfm( int nUnit, int addr, int nDevCnt, LPBYTE data )
{
BYTE buf[530];//最大524
LPBYTE p = &buf[4];
int i, n, byt;

while( nDevCnt > 0 )
{
if(m_nUartStopFlag != 0 )
return FALSE;

if( nDevCnt > 127 )
n = 127;
else
n = nDevCnt;

p[0] = 0xf1;
p[1] = ((nUnit<<4)&0xf0) | ((addr>>12)&0xf);

p[2] = (addr>>4)&0xff;
p[3] = (addr<<4)&0xf0;
p = &p[3];

byt = n*2;//字节数
*p++ |= (byt>>4 ) & 0xf;
*p = (byt<<4) & 0xf0;
//数据
for( i=0; i<byt; i++ )
{
int Q = *data++;
*p++ |= (Q>>4 ) & 0xf;
*p = (Q<<4) & 0xf0;
}

for( i = 0; i < MAX_UART_TRY; i++ )
{
SendReq( buf, n*4 + 9 );
if( WriteDevice_Ack() )
break;
if( m_nUartStopFlag != 0 )
return FALSE;
ReShakeHandle(1);
}
if( i == MAX_UART_TRY )
return FALSE;
nDevCnt -= n;
addr += byt;
data += byt;
}
return TRUE;

}

其中:typedef BYTE far *LPBYTE;
typedef unsigned char BYTE;
C#代码(自己编译的):
  public unsafe bool WriteBfm(int nUnit, int addr, int nDevCnt, byte* data)
{

byte[] buf = new byte[530];
fixed (byte* pbuf = buf)
{
fixed (byte* p = &buf[4])
{
int i, n, byt;
while (nDevCnt > 0)
{
if (m_nUartStopFlag != 0)
return false;

if (nDevCnt > 127)
n = 127;
else
n = nDevCnt;

p[0] = 0xf1;
p[1] = (byte)(((nUnit << 4) & 0xf0) | ((addr >> 12) & 0xf));

p[2] = (byte)((addr >> 4) & 0xff);
p[3] = (byte)((addr << 4) & 0xf0);



p = &p[3];

byt = n * 2;//字节数
*p++ |= (byte)((byt >> 4) & 0xf);
*p = (byte)((byt << 4) & 0xf0);
//数据
for (i = 0; i < byt; i++)
{
int Q = *data++;
*p++ |= (byte)((Q >> 4) & 0xf);
*p = (byte)((Q << 4) & 0xf0);
}

for (i = 0; i < MAX_UART_TRY; i++)
{
SendReq(pbuf, n * 4 + 9);
if (WriteDevice_Ack())
break;
if (m_nUartStopFlag != 0)
return false;
ReShakeHandle(1);
}
if (i == MAX_UART_TRY)
return false;
nDevCnt -= n;
addr += byt;
data += byt;
}
return true;

}

}


}


调试时报错:错误:“p”是一个“固定变量”,无法为它赋值
我想可能是我这行代码的原因: fixed (byte* p = &buf[4]) 不知该怎样修改,求教,谢谢。

B:
原代码大概有1500行左右,感觉这样编译太慢,而且工作量比较大(主要是我对C++不熟),不知大家有没有好的点的方法推荐下。谢谢。

C:
听人说,可以把原码封装成类,然后再在C#中调用,但要考虑方法(函数)的参数类型转换问题。我不知这个具体是怎样实现的,是否跟我现在这样完全用C#编译原码??????想了解下具体的实现过程中。谢谢。



[解决办法]
把C++的编译成dll,在C#中调用这个dll里的函数
[解决办法]
引用:
Quote: 引用:

用C#编译C的源代码?你没有睡醒还在做梦吧。还有你的老板。


大哥,请不要再回这样的贴子好吗?有时间就帮我想想应该怎样解决问题才是正道。

打算这样做“把C++的编译成dll,在C#中调用这个dll里的函数”正在找资料中,如果有就施舍点,谢谢

注解:鄙人对C#熟点,对C++也就停留在上学那会,老板对C熟点,对C#白纸,也没时间做项目类的活。谢谢


首先,先悲哀一个,为中国的程序事业默哀

然后,2楼的意思是,pinvoke,自己查查吧,但是也是要改C++的代码,读不懂我也没有办法
[解决办法]
你这个不需要用指针写呀,直接操作数组即可。

还有,你可以在C++中导出WriteBfm这个函数,然后用C#调用C++的dll,很容易的
[解决办法]
补充一句:你的错误在于p = &p[3];

对于你的代码,把

byte[] buf = new byte[530];

改为

byte* pbuf = stackalloc byte[530];

把数组分配到栈里,本身就是固定的,而且性能更好,后面直接byte* p = &buf[4],不用fixed
[解决办法]
可以考虑用 C++/CLI
[解决办法]
com wrap
[解决办法]
引用:
Quote: 引用:

你这个不需要用指针写呀,直接操作数组即可。

还有,你可以在C++中导出WriteBfm这个函数,然后用C#调用C++的dll,很容易的


你好,非常感谢你的回帖,我也正打算将C++中的函数导出,然后一个一个做成dll,但现在发现一问题就是原C++中的函数很多都是嵌套调用的,不知你注意到我上面的C++代码没,里面就嵌套调用用了几个函数(上面只是原码中一个函数,还有很多类的)。不知该如何解决,请明示。谢谢。


这个不是什么问题吧,它嵌套它的,你只需要把你最终C#需要调用的函数导出即可,其他都是dll内部你要导出的函数来实现的
[解决办法]
意思就是叫你用c++做一个包装,把OOP的东西隐藏起来,以平面的纯C接口公开。
当然你也可以选择把它改造成com组件。
[解决办法]
回14楼内容:
1.在C#中你需要调用哪个函数你就导出哪个函数即可,对于你的问题1,你说的没错
2.对于你的问题2,不需要转换成C#呀,你只需要在C#里面调用你用C++写的dll即可,例如你自己的例子:
C++中导出

EXTERN_C __declspec(dllexport) BOOL WINAPI ExportedWriteBfm(int nUnit,int addr,int nDevCnt,LPBYTE data)
{
return CDGX::WriteBfm(int nUnit,int addr,int nDevCnt,LPBYTE data);
}

C#中引用

[DllImport("ExportedWriteBfm",CallingConvention=CallingConvention.StdCall)]
public unsafe static extern bool ExportedWriteBfm(int nUnit,int addr,int nDevCnt,byte* data);

[解决办法]
你首先要明白那个WriteBfm函数的作用,之后才能考虑如何转换或调用。
初步看下来,函数功能是往外设写入一组数据,写入的是data参数里面的内容,函数内部构造了一个缓存数组buf,最终发送到设备上的是这个buf里面的内容,这个内容的要求是,开始四字节为地址,固定格式:
p[0] = 0xf1;
p[1] = ((nUnit<<4)&0xf0)
[解决办法]
((addr>>12)&0xf);
p[2] = (addr>>4)&0xff;
p[3] = (addr<<4)&0xf0;
后面的都是数据部分,整个数据结构就是如此。

下面就考虑如何处理这种收发模式。如果你的外设是通过COM口处理的,那么可以直接用C#的类来收发数据,将数据部分的封装处理用C#来处理,否则就对C++编译为带导出函数的dll,再或者直接新建C++/CLR项目,将原C++代码复制到新项目里。
如果你可以找到外设的最新C#接口,就不用那么麻烦了,现在新出的串口设备,一般都会带有C#的接口而不再给C++的接口了,因为C#的封装会给使用带来巨大的便利,且不会暴露自己的核心代码。

读书人网 >C#

热点推荐