C#与C++联合编程之C++生成dll

一.介绍

本项目是接收卫星视频流,并将视频播出,同时可在视频上编辑字幕的内容、位置、字体大小等。字幕编辑功能是通过C++编写的dll文件来实现,C#调用dll完成字幕编辑功能,这个功能将在下一篇文章中描述,C#调用dll

二.步骤

1.以vs2015为开发平台,选择“文件->新建项目”
2.在模板-Visual C++中找到MFC DLL
在这里插入图片描述
3.接来下按照提示一步一步完成新建项目。

三.代码

1.申明

extern "C" void CG_DLL_EXP _cdecl loadText2(TCHAR *strText,int uiTextX,int uiTextY,PULONG pTextBuffer,int x,int y,int fHeight,int fWidth,TCHAR *fontStr,int r,int g,int b);

extern "C" void CG_DLL_EXP _cdecl loadText3(TCHAR *strText,int uiTextX,int uiTextY,PULONG pTextBuffer,int x,int y,int &bmw,int fh,int fw,TCHAR *fontStr,int r,int g,int b);

extern "C" void CG_DLL_EXP _cdecl backPic(bool ifBack,TCHAR * strText,int uiTextX,int uiTextY,PULONG pTextBuffer,int x,int y);

extern "C" void CG_DLL_EXP _cdecl loadText(TCHAR *strText1,int uiTextX,int uiTextY,PULONG pTextBuffer,int x,int y,TCHAR *fontStr,int r,int g,int b);

extern "C" void CG_DLL_EXP _cdecl AreaMove(ULONG fieldNo,PULONG pCgSrcBuffer,PULONG pCgDecBuffer,ULONG ulWidth,ULONG ulHeight,ULONG ulMoveDirection,ULONG ulMoveStep,LONG &m_ulUp);
extern "C" void CG_DLL_EXP _cdecl AreaMove2(PULONG pCgSrcBuffer,PULONG pCgDecBuffer,ULONG ulWidth,ULONG ulHeight,ULONG ulMoveStep,int bmw);

3.代码之实现

void AreaMove(ULONG fieldNo,PULONG pCgSrcBuffer,PULONG pCgDecBuffer,ULONG ulWidth,ULONG ulHeight,ULONG ulMoveDirection,ULONG ulMoveStep,LONG &m_ulUp)
{
	unsigned int j;
	static int left = 0;
	static ULONG LastFieldNo ;
	static bool FirstField = true ;
	static ULONG MoveDiretion = 0;
	ULONG test[1920];
	if(!pCgSrcBuffer&&!pCgDecBuffer)return;

	if (FirstField)
	{
		FirstField = false ;
	}
	else
	{
		if (LastFieldNo + 1 != fieldNo)
			TRACE("error! LastFieldNo : %d, fieldNo : %d\n", LastFieldNo, fieldNo);
	}
	LastFieldNo = fieldNo ;
	CString str;
	//MessageBox(NULL,_T("start"),NULL,NULL);
	switch( ulMoveDirection )
	{
	case 0:
		switch( MoveDiretion )
		{
		case 0:		
		case 1:
		case 2:
			//MessageBox(NULL,_T("1"),NULL,NULL);
			for( j = ( fieldNo + 1 )% 2;j<ulHeight;j+=2 )
			{						
				if( ( j + m_ulUp ) < ulHeight )
					memcpy(&pCgDecBuffer[j*ulWidth],&pCgSrcBuffer[( j + m_ulUp )*ulWidth],ulWidth*4);						
				else
					memcpy(&pCgDecBuffer[j*ulWidth],&pCgSrcBuffer[( j + m_ulUp-ulHeight )*ulWidth],ulWidth*4);		
			}			
			break;
		case 3:			
		case 4:
			//MessageBox(NULL,_T("2"),NULL,NULL);
			for( j = ( fieldNo + 1 )% 2;j<ulHeight;j+=2 )
			{	
				memcpy(&pCgDecBuffer[j*ulWidth],&pCgSrcBuffer[ j*ulWidth+left],(ulWidth-left)*4);
				memcpy(&pCgDecBuffer[j*ulWidth+ulWidth-left],&pCgSrcBuffer[ j*ulWidth],left*4);	
			}		
			break;
		}		 
		break;
	case 1	:// m_ulUp
		m_ulUp += ulMoveStep;
		m_ulUp = m_ulUp % ulHeight;
		MoveDiretion = ulMoveDirection;
		//MessageBox(NULL,_T("3"),NULL,NULL);
		for( j = ( fieldNo + 1 )% 2;j<ulHeight;j+=2 )
		{					
			if( ( j + m_ulUp ) < ulHeight )
				memcpy(&pCgDecBuffer[j*ulWidth],&pCgSrcBuffer[( j + m_ulUp )*ulWidth],ulWidth*4);						
			else
				memcpy(&pCgDecBuffer[j*ulWidth],&pCgSrcBuffer[( j + m_ulUp-ulHeight )*ulWidth],ulWidth*4);		
		}

		break;

	case 2	:// Down
		m_ulUp -= ulMoveStep;
		MoveDiretion = ulMoveDirection;
		if( m_ulUp < 0 )
			m_ulUp = m_ulUp + ulHeight;
		m_ulUp = m_ulUp % ulHeight;
		//MessageBox(NULL,_T("4"),NULL,NULL);
		for( j = ( fieldNo+1)% 2;j<ulHeight;j+=2 )
		{					
			if( ( j + m_ulUp ) < ulHeight )
				memcpy(&pCgDecBuffer[j*ulWidth],&pCgSrcBuffer[( j + m_ulUp )*ulWidth],ulWidth*4);						
			else
				memcpy(&pCgDecBuffer[j*ulWidth],&pCgSrcBuffer[( j + m_ulUp-ulHeight )*ulWidth],ulWidth*4);	
		}

		break;

	case 4	:
		left -= ulMoveStep;
		MoveDiretion = ulMoveDirection;
		if( left < 0 )
			left = ulWidth + left;

		for( j = ( fieldNo + 1 )% 2;j<ulHeight;j+=2 )
		{	
			memcpy(&pCgDecBuffer[j*ulWidth],&pCgSrcBuffer[ j*ulWidth+left],(ulWidth-left)*4);
			memcpy(&pCgDecBuffer[j*ulWidth+ulWidth-left],&pCgSrcBuffer[ j*ulWidth],left*4);	
		}

		break;

	case 3	:				
		left += ulMoveStep;
		MoveDiretion = ulMoveDirection;
		left = left % ulWidth;
		//str.Format(_T("ulHeight=%d"),ulHeight);
		//MessageBox(NULL,str,NULL,NULL);
		for( j = ( fieldNo + 1 )% 2;j<ulHeight;j+=2 )
		{	
			//str.Format(_T("j*ulWidth=%d;j*ulWidth+left=%d;"),j);
			//MessageBox(NULL,str,NULL,NULL);
			memcpy(&pCgDecBuffer[j*ulWidth],&pCgSrcBuffer[ j*ulWidth+left],(ulWidth-left)*4);
			memcpy(&pCgDecBuffer[j*ulWidth+ulWidth-left],&pCgSrcBuffer[ j*ulWidth],left*4);	
		}		
		break;
	}
	return;
}

void AreaMove2(PULONG pCgSrcBuffer,PULONG pCgDecBuffer,ULONG ulWidth,ULONG ulHeight,ULONG ulMoveStep,int bmw)
{
	unsigned int j;
	static int left = 0;   //重复调用,不是重复值
	static int left2 = 0;  //图片内存偏移量
	if(!pCgSrcBuffer&&!pCgDecBuffer)return;

	left += ulMoveStep;
	left2 += ulMoveStep;
	left = left % ulWidth;
	for( j = 0;j<ulHeight;j+=1 )
	{	
		memcpy(&pCgDecBuffer[j*ulWidth],&pCgSrcBuffer[ j*bmw+left2],ulWidth*4);

	}
	left2 = left2 % bmw;
}


void loadText2(TCHAR *strText1,int uiTextX,int uiTextY,PULONG pTextBuffer,int x,int y,int fHeight,int fWidth,TCHAR *fontStr,int r,int g,int b)
{
	CString strText(strText1);
	CString str;
	CSize uiVideoSize(x,y);
	memset(pTextBuffer,0,1920*1080);
	if((pTextBuffer == NULL))
		return ;

	CBitmap * pBitmap ;
		pBitmap = new CBitmap;
		CClientDC dc(NULL);
		CDC memDC;
		// 		
		ULONG *pPicture,*ptemp,ulLeftDistance,ulUpDistance;
		//CString bless ;

		CFont font1;
		COLORREF colorbk,colortext;
		unsigned int i,j,k,bmw,bmh,sizebl;
		ULONG pa,pr,pb,pg,pels,pelsf,pelsb;

		//创建字体对话框对象
		CFontDialog dlg;
		//修改字体对话框相关属性
		dlg.m_cf.Flags |= CF_USESTYLE;
		colortext=RGB(r,g,b);
		LOGFONT lf;
		memset(&lf,0,sizeof(LOGFONT));

		lf.lfWidth=uiVideoSize.cx/48+fWidth;                  //以后用字体对话框代替
		lf.lfHeight=lf.lfWidth*7/4+fHeight;

// 
// 		str.Format(_T("lfWidth:%d, lfHeight:%d"),lf.lfWidth,lf.lfHeight);
// 		MessageBox(NULL,str,NULL,NULL);

		//lf.lfWeight=1000;
		CString lfontStr(fontStr);
		_tcscpy((TCHAR*)&(lf.lfFaceName),lfontStr);
		font1.CreateFontIndirect(&lf); //创建字体
		colorbk=RGB(0,0,0);
		memDC.CreateCompatibleDC(&dc); //创建DC
		memDC.SelectObject(&font1);//将字体选入设备描述表
#ifdef UNICODE
		sizebl=strText.GetLength()*2+1;   //1:修正量 //7
// 		str.Format(_T("getLength(sizebl):%d"),sizebl);
// 		MessageBox(NULL,str,NULL,NULL);
// 
// 		sizebl = sizeof(strText);
// 		
#else
		sizebl=strText.GetLength()+1;   //1:修正量
#endif
// 		str.Format(_T("sizeof(sizebl):%d"),sizebl);
// 		MessageBox(NULL,str,NULL,NULL);


		//str.Format(_T("字间距:%d"),memDC.GetTextCharacterExtra());

		//MessageBox(NULL,str,NULL,NULL);

		bmw=lf.lfWidth*sizebl+memDC.GetTextCharacterExtra()*sizebl;
		bmh=lf.lfHeight+2;
		pBitmap->CreateCompatibleBitmap(&dc,bmw,bmh);
		CBitmap *pOld=memDC.SelectObject(pBitmap); 
		//memDC.FillSolidRect(0,0,bmw,bmh,RGB(10,10,10));
		memDC.FillSolidRect(0,0,bmw,bmh,RGB(0,0,0));
		memDC.SetBkColor(colorbk);
		memDC.SetTextColor(colortext);
		memDC.TextOut(0,1,strText);



 		//str.Format(_T("宽是:%d, 高是:%d"),bmw,bmh);
 		//MessageBox(NULL,str,NULL,NULL);
		pPicture = new ULONG[ bmw*bmh];
		ptemp=new ULONG[ bmw*bmh ];
		pBitmap ->GetBitmapBits(bmw*bmh*4,pPicture);
		for( i=0;i<bmw*bmh ;i++)
		{
			if (pPicture[i]!=0x00000000)            //如果不是黑色.颜色的16进制,可为任意颜色
				pPicture[i]=pPicture[i]|0xff000000;  //按位作或操作,使alpha通道为255
		}


		memcpy(ptemp,pPicture,bmw*bmh*4);

		if( uiVideoSize.cx > bmw)
			ulLeftDistance = uiTextX;
		else
			ulLeftDistance = 0; 
		ulUpDistance = uiTextY;
		//MessageBox(NULL,_T("1"),NULL,NULL);
	//开始写数据到字幕卡缓存
		for( j=0;j<uiVideoSize.cy;j++ )
		{
			if( ( j < ( bmh + ulUpDistance ) ) && ( j >= ulUpDistance /*+2*/))
			{
				for( k=0; k<uiVideoSize.cx; k++ )

					if( ( k < ( /*tmp*/bmw + ulLeftDistance ) ) && ( k >= ulLeftDistance ) )
					{
						//MessageBox(NULL,_T("2"),NULL,NULL);
							pTextBuffer[ j*uiVideoSize.cx  + k ] = ( pPicture[ ( j - ulUpDistance )*bmw + k - ulLeftDistance ] );
					}
					else
					{
						//MessageBox(NULL,_T("3"),NULL,NULL);
						pTextBuffer[ j*uiVideoSize.cx  + k ] = 0;
					}
			}
			else
			{
				/*MessageBox(NULL,_T("4"),NULL,NULL);*/
				for( k=0; k<uiVideoSize.cx ; k++ )
				{
// 					str.Format(_T("j是:%d, j*uiVideosize.cx+k是:%d"),j,j*uiVideoSize.cx  + k);
// 					MessageBox(NULL,str,NULL,NULL);
					pTextBuffer[ j*uiVideoSize.cx  + k ] = 0;
				}
				/*MessageBox(NULL,_T("5"),NULL,NULL);*/
			}
		}
		delete [] ptemp;
		delete [] pPicture;
		memDC.SelectObject(pOld);
		delete pBitmap;
		font1.~CFont();
}

void loadText3(TCHAR *strText1,int uiTextX,int uiTextY,PULONG pTextBuffer,int x,int y,int &bmw,int fh,int fw,TCHAR *fontStr,int r,int g,int b)
{
	CString strText(strText1);
	CString str;
	CSize uiVideoSize(x,y);
	memset(pTextBuffer,0,1920*1080);

	if((pTextBuffer == NULL))
		return ;

	CBitmap * pBitmap ;
	pBitmap = new CBitmap;
	CClientDC dc(NULL);
	CDC memDC;
	// 		
	ULONG *pPicture,*ptemp,ulLeftDistance,ulUpDistance;
	//CString bless ;

	CFont font1;
	COLORREF colorbk,colortext;
	unsigned int i,j,k,bmh,sizebl;
	ULONG pa,pr,pb,pg,pels,pelsf,pelsb;

	//创建字体对话框对象
	CFontDialog dlg;
	//修改字体对话框相关属性
	dlg.m_cf.Flags |= CF_USESTYLE;
	colortext=RGB(r,g,b);
	LOGFONT lf;
	memset(&lf,0,sizeof(LOGFONT));

	lf.lfWidth=uiVideoSize.cx/48+fw;                  //以后用字体对话框代替
	lf.lfHeight=lf.lfWidth*7/4+fh;

	// 
	// 		str.Format(_T("lfWidth:%d, lfHeight:%d"),lf.lfWidth,lf.lfHeight);
	// 		MessageBox(NULL,str,NULL,NULL);

	//lf.lfWeight=1000;
	CString lfontStr(fontStr);
	_tcscpy((TCHAR*)&(lf.lfFaceName),lfontStr);
	font1.CreateFontIndirect(&lf); //创建字体
	colorbk=RGB(0,0,0);
	memDC.CreateCompatibleDC(&dc); //创建DC
	memDC.SelectObject(&font1);//将字体选入设备描述表
#ifdef UNICODE
	sizebl=strText.GetLength()*2+1;   //1:修正量 //7
	// 		str.Format(_T("getLength(sizebl):%d"),sizebl);
	// 		MessageBox(NULL,str,NULL,NULL);
	// 
	// 		sizebl = sizeof(strText);
	// 		
#else
	sizebl=strText.GetLength()+1;   //1:修正量
#endif
	// 		str.Format(_T("sizeof(sizebl):%d"),sizebl);
	// 		MessageBox(NULL,str,NULL,NULL);


	//str.Format(_T("字间距:%d"),memDC.GetTextCharacterExtra());



	bmw=lf.lfWidth*sizebl+memDC.GetTextCharacterExtra()*sizebl;
	bmh=lf.lfHeight+2;
	pBitmap->CreateCompatibleBitmap(&dc,bmw,bmh);
	CBitmap *pOld=memDC.SelectObject(pBitmap); 
	//memDC.FillSolidRect(0,0,bmw,bmh,RGB(10,10,10));
	memDC.FillSolidRect(0,0,bmw,bmh,RGB(0,0,0));
	memDC.SetBkColor(colorbk);
	memDC.SetTextColor(colortext);
	memDC.TextOut(0,1,strText);


	pPicture = new ULONG[ bmw*bmh*10];//10代表可输出的行数
	ptemp=new ULONG[ bmw*bmh ];
	pBitmap ->GetBitmapBits(bmw*bmh*4,pPicture);
	for( i=0;i<bmw*bmh;i++)
	{
		if (pPicture[i]!=0x00000000)            //如果不是黑色.颜色的16进制,可为任意颜色
			pPicture[i]=pPicture[i]|0xff000000;  //按位作或操作,使alpha通道为255
	}



	if( uiVideoSize.cx > bmw)
	{
		ulLeftDistance = uiTextX;
	}
	else
	{
		ulLeftDistance = 0;

	}
	ulUpDistance = uiTextY;
	for( j=0;j<uiVideoSize.cy;j++ )
	{
		if( ( j < ( bmh + ulUpDistance ) ) && ( j >= ulUpDistance ))
		{
			for( k=0; k< bmw /*uiVideoSize.cx*/; k++ )
			{
				if(  k < ( bmw + ulLeftDistance)  && ( k >= ulLeftDistance ) )
				{
					pTextBuffer[ j*bmw+k ] = ( pPicture[ ( j - ulUpDistance )*bmw + k - ulLeftDistance ] );
				}
				else
				{
					pTextBuffer[ j*bmw  + k ] = 0;
				}

			}
		}
		else
		{
			for( k=0; k< bmw/*uiVideoSize.cx*/ ; k++ )
			{
				
				pTextBuffer[ j*bmw  + k ] = 0;
			}
		}
		
	}
	delete [] ptemp;
	delete [] pPicture;
	memDC.SelectObject(pOld);
	delete pBitmap;
	font1.~CFont();
}

PULONG m_pText = new ULONG[1920*1080];
void loadText(TCHAR *strText1,int uiTextX,int uiTextY,PULONG pTextBuffer,int x,int y,TCHAR *fontStr,int r,int g,int b)
{
	CString strText(strText1);
	CString str;
	CSize uiVideoSize(x,y);


	if((pTextBuffer == NULL))
		return ;

	CBitmap * pBitmap ;
	pBitmap = new CBitmap;
	CClientDC dc(NULL);
	CDC memDC;
	// 		
	ULONG *pPicture,*ptemp,ulLeftDistance,ulUpDistance;
	//CString bless ;

	CFont font1;
	COLORREF colorbk,colortext;
	unsigned int i,j,k,bmw,bmh,sizebl;
	ULONG pa,pr,pb,pg,pels,pelsf,pelsb;

	//创建字体对话框对象
	CFontDialog dlg;
	//修改字体对话框相关属性
	dlg.m_cf.Flags |= CF_USESTYLE;
	colortext=RGB(r,g,b);
	LOGFONT lf;
	memset(&lf,0,sizeof(LOGFONT));

	lf.lfWidth=uiVideoSize.cx/48;                  //以后用字体对话框代替
	lf.lfHeight=lf.lfWidth*7/4;
// 	str.Format(_T("lfWidth:%d, lfHeight:%d"),lf.lfWidth,lf.lfHeight);
// 	MessageBox(NULL,str,NULL,NULL);

	lf.lfWeight=1000;
	CString lfontStr(fontStr);
	_tcscpy((TCHAR*)&(lf.lfFaceName),lfontStr);
	font1.CreateFontIndirect(&lf); //创建字体
	colorbk=RGB(0,0,0);
	memDC.CreateCompatibleDC(&dc); //创建DC
	memDC.SelectObject(&font1);//将字体选入设备描述表
#ifdef UNICODE
	sizebl=strText.GetLength()*2+1;   //1:修正量 //7
	// 		str.Format(_T("getLength(sizebl):%d"),sizebl);
	// 		MessageBox(NULL,str,NULL,NULL);
	// 
	// 		sizebl = sizeof(strText);
	// 		
#else
	sizebl=strText.GetLength()+1;   //1:修正量
#endif
	// 		str.Format(_T("sizeof(sizebl):%d"),sizebl);
	// 		MessageBox(NULL,str,NULL,NULL);


	//str.Format(_T("字间距:%d"),memDC.GetTextCharacterExtra());

	//MessageBox(NULL,str,NULL,NULL);

	bmw=lf.lfWidth*sizebl+memDC.GetTextCharacterExtra()*sizebl;
	bmh=lf.lfHeight+2;
	pBitmap->CreateCompatibleBitmap(&dc,bmw,bmh);
	CBitmap *pOld=memDC.SelectObject(pBitmap); 
	//memDC.FillSolidRect(0,0,bmw,bmh,RGB(10,10,10));
	memDC.FillSolidRect(0,0,bmw,bmh,RGB(0,0,0));
	memDC.SetBkColor(colorbk);
	memDC.SetTextColor(colortext);
	memDC.TextOut(0,1,strText);



	//str.Format(_T("宽是:%d, 高是:%d"),bmw,bmh);
	//MessageBox(NULL,str,NULL,NULL);
	pPicture = new ULONG[ bmw*bmh ];
	ptemp=new ULONG[ bmw*bmh ];
	pBitmap ->GetBitmapBits(bmw*bmh*4,pPicture);
	for( i=0;i<bmw*bmh ;i++)
	{
		if (pPicture[i]!=0x00000000)            //如果不是黑色.颜色的16进制,可为任意颜色
			pPicture[i]=pPicture[i]|0xff000000;  //按位作或操作,使alpha通道为255
	}
	memcpy(ptemp,pPicture,bmw*bmh*4);

	if( uiVideoSize.cx > bmw)
		ulLeftDistance = uiTextX;
	else
		ulLeftDistance = 0;
	ulUpDistance = uiTextY;
/*	MessageBox(NULL,_T("1"),NULL,NULL);*/
	//开始写数据到字幕卡缓存
	for( j=0;j<uiVideoSize.cy;j++ )
	{
		if( ( j < ( bmh + ulUpDistance ) ) && ( j >= ulUpDistance /*+2*/))
		{
			for( k=0; k<uiVideoSize.cx; k++ )

				if( ( k < ( /*tmp*/bmw + ulLeftDistance ) ) && ( k >= ulLeftDistance ) )
				{
/*					MessageBox(NULL,_T("2"),NULL,NULL);*/
					m_pText[ j*uiVideoSize.cx  + k ] = ( pPicture[ ( j - ulUpDistance )*bmw + k - ulLeftDistance ] );
				}
				else
				{
/*					MessageBox(NULL,_T("3"),NULL,NULL);*/
					m_pText[ j*uiVideoSize.cx  + k ] = 0;
				}
		}
		else
		{
			//MessageBox(NULL,_T("4"),NULL,NULL);
			for( k=0; k<uiVideoSize.cx ; k++ )
			{
				m_pText[ j*uiVideoSize.cx  + k ] = 0;
			}
	
		}
	}
	
	delete [] ptemp;
	delete [] pPicture;
	memDC.SelectObject(pOld);
	delete pBitmap;
	MessageBox(NULL,_T("6"),NULL,NULL);
	while (true)
	{
// 		AreaMove(1,m_pText,pTextBuffer,x,y,3,2,m_);
// 
// 		AreaMove(0,m_pText,pTextBuffer,x,y,3,2);
	}
	
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

muyiliu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值