第一部分 c++
关键程序文件:
xxx.idl
2 [id( 4 )] short IReadPort(unsigned char * inPArr1);//byte类型接口, 在非托管语言中可以正常使用,托管语言中无法正常传入数组
3 [id( 3 )] short I1( void * a1);//与c#的传入System.InPtr类型对应。
xxxCtrl.h
public :
enum {
};
short IReadPort(unsigned char inPArr1[]);//程序内接口定义
short I1( void * a2);//
};
xxxCtrl.cpp
BEGIN_DISPATCH_MAP(CSCMUSBBULKCtrl, COleControl)
DISP_FUNCTION_ID(CSCMUSBBULKCtrl, " AboutBox " , DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
DISP_FUNCTION_ID(CSCMUSBBULKCtrl, " IReadPort " , 4 ,IReadPort, VT_I2 , VTS_PI2) // fchen
// DISP_FUNCTION_ID(CSCMUSBBULKCtrl,"I1",3,I1, VT_I2 , VTS_PI2) // fchen
DISP_FUNCTION_ID(CSCMUSBBULKCtrl, " I1 " , 3 ,I1, VT_I2 ,VTS_I4) //void* 作为地址是一个整型数据,不能用VTS_PI4(C#中调用时会报错).vb调用时2中类型可能都可以。
short CSCMUSBBULKCtrl::IReadPort(unsigned char inPArr[])
{
short Rel = 99 ;
inPArr[ 0 ] = 9 ;
inPArr[ 1 ] = 7 ;
inPArr[ 2 ] = 6 ;
inPArr[ 3 ] = 5 ;
return Rel;
}
short CSCMUSBBULKCtrl::I1( void * a2)
{
unsigned char c1[ 20 ];
unsigned char * psz;
psz = (unsigned char * )a2;
memcpy( c1, psz, 10 );//更新数据后传回数组
c1[ 0 ] = 9 ;
c1[ 1 ] = 9 ;
c1[ 2 ] = 9 ;
c1[ 3 ] = 9 ;
c1[ 4 ] = 9 ;
c1[ 5 ] = 9 ;
c1[ 6 ] = 9 ;
memcpy( a2, c1, 10 );//更新数据后传回数组
short Rel = 8 ;
return Rel;
}
c#调用
使用ocx前先引入com组件
byte [] b = { 1 , 2 , 3 , 4 , 5 };
short c = 1 ;
byte [] managedArray = { 1 , 2 , 3 , 4 };
// Initialize unmanged memory to hold the array.
int size = Marshal.SizeOf(managedArray[ 0 ]) * managedArray.Length;
IntPtr pnt = Marshal.AllocHGlobal(size);
try
{
// Copy the array to unmanaged memory.
Marshal.Copy(managedArray, 0 , pnt, managedArray.Length);//建立非托管数组
c = this .axSCMUSBBULK1.I1(pnt);//IntPtr与接口的vodi*对应
// Copy the unmanaged array back to another managed array.
byte [] managedArray2 = new byte [managedArray.Length];
Marshal.Copy(pnt, managedArray2, 0 , managedArray.Length);//返回处理后的非托管数组,转会为托管数组。
}
finally
{
// Free the unmanaged memory.
Marshal.FreeHGlobal(pnt);
}
// SCMUSBBULKLib.SCMUSBBULK tt=new SCMUSBBULKLib.SCMUSBBULK();//此方式建立的对象调用时报错!
// c = tt.I1(pnt);
混合程序调试:
以c#程序为容器调试ActiveX时需要设置调试器:
配置属性->调试->调试器类型 设为"混合"或"仅限本机", 而不能使用默认的"自动".
否则无法进入ActiveX的断点。
c#中
short[] lArray = new short[512 * 512];
dicom.getBuff(out lArray[0]);
c++中
idl:中
[id(5)] HRESULT getBuff([out] SHORT* pBuff);
函数实现:
STDMETHODIMP CIDicomDS::getBuff(SHORT* pBuff)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: 在此添加实现代码
int nRow = DicomViewPara->m_pDicomFileInfo->m_nImageLine;
int nColumn = DicomViewPara->m_pDicomFileInfo->m_nImageColumn;
memset(pBuff,0, nRow*nColumn*2);
memcpy(pBuff,DicomViewPara->m_pOriginal,nRow*nColumn*2);
//SHORT c1[6];
//SHORT* psz;
//psz = (SHORT*)pBuff;
//memcpy( c1, psz, 12);//更新数据后传回数组
//c1[0]=10;
//c1[1]=11;
//c1[2]=12;
//c1[3]=13;
//c1[4]=14;
//c1[5]=15;
//memcpy( pBuff, c1, 12);//更新数据后传回数组
return S_OK;
}