VS2010产生C的dll方法和C#调用方式

第一部分:产生C的dll html

http://210.43.24.222/chy/3sbase/news/?766.html(资料来源,有改动)
一、 1,新建win32工程,选中DLL项目,以下图:

2,分别添加头文件和cpp文件 算法

// CDLL.h头文件
#ifndef LIB_H
#define LIB_H
extern "C" _declspec(dllexport) int add(int x,int y);    // 声明为C编译、连接方式的外部函数
extern "C" _declspec(dllexport) int sub(int x,int y);    // 声明为C编译、连接方式的外部函数
/* 加入任意你想加入的函数定义*/
#endif
// CDLL.cpp文件
#include "stdafx.h"
#include "CDLL.h"//貌似这两个头文件的顺序不能颠倒。我试了不少次,可是不能肯定。

int add(int x,int y)//是否能够理解为,VS2010已经默认是 _stdcall,因此函数不用添加该修饰符
{
    return x+y;
}

int sub(int x,int y)
{
    return x-y;
}


//上面的代码可能会致使
error C2059: syntax error : 'string'  
的问题。借鉴网上的提供的经验http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/eb89a44d-35cb-4ad0-88ce-cf9664c9fcbc。说法很混乱。但通过本人的调试,发现若是是正常的C++的编译链接器,则不会出现问题。若是对应的是 CDLL.c文件,不是CDLL.cpp文件,可能出现上述问题。
若是跟CDLL.c文件,则改成下面形式,不会出现error c2059:syntax error:'string'  c#

extern _declspec(dllexport) int add(int x,int y);    // 声明为C编译、连接方式的外部函数
extern _declspec(dllexport) int sub(int x,int y);    // 声明为C编译、连接方式的外部函数
暂时尚未发现其余问题。

3,按F6编译,在相应的Debug文件夹里面能够找到生成的.dll文件。 less

第二部分:C#调用方式dll 函数


1,创建一个工程,而后在SolutionExplorer窗口,选中须要动态连接库(DLL)的工程(project),右击添加已有文件,选择上面生成的.dll文件,而后加入到工程中来。
2,在SolutionExplorer窗口,选中该文件,在下面Properties窗口中,更改其 ui

3,在C#程序中加入以下代码,就可使用了。 spa

class Program
    {
        //下面的语句解决问题的说明见
        // http://blog.csdn.net/xuehuic/article/details/7682793
        [DllImport("CDLL.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        extern static int add(int a, int b);

        [DllImport("CDLL.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
        extern static int sub(int a, int b);

        static void Main(string[] args)
        {
            Console.WriteLine(add(10, 2).ToString());
            Console.WriteLine(sub(10, 2).ToString());
            Console.Read();
        }
    }
第三部分:把通常的可执行C,CPP改成dll

一、为了便于改下已经存在的c或者cpp项目,能够按照第一部分的作法先新建一个.dll工程。便于下面修改代码。假设新建的.dll动态库的工程为NewDll,待改动的C或CPP工程为OldC,下面以修改某个GSM_AMR算法为.dll动态连接库做例子,说明过程。 .net

二、用VS2010打开OldC,右击OldC工程,添加已存在文件,找到NewDll文件夹里面的dllmain.cpp文件,按F6,若是报错,看缺乏那些头文件。通常BOOL被报错,说明缺乏stdax.h等,一直添加NewDll工程里面的头文件,直至可能提醒可能#include “XXXX.h”不存在。通常这是因为该头文件和其余头文件不在同一个目录下,能够将他们调整到同一个目录下面。 调试

三、右击OldC工程的Properties属性,打开,修改输出类型为DLL,而不是.exe文件。这个能够本身慢慢找,总会找到的,通常打开的窗口就是能够修改输出类型的。 code

四、按F10找到OldC的主函数main(),通常main()所在的文件都没有对应的头文件。能够为他创建一个同名头文件,按照第一部分里面的说明,把main()函数里面的头文件都复制到该同名头文件里,而后添加第一部分的代码CDLL.h里面的以下代码。

// CDLL.h头文件
#ifndef LIB_H
#define LIB_H
extern "C" _declspec(dllexport) int add(int x,int y);    // 声明为C编译、连接方式的外部函数
extern "C" _declspec(dllexport) int sub(int x,int y);    // 声明为C编译、连接方式的外部函数
/* 加入任意你想加入的函数定义*/
#endif
修改为你想要的函数格式。

五、在main()所在的文件里面添加你所须要的函数体。

6,按F6,应该出现Build success,若是出现什么问题,极有多是上面第一部分提的那个问题,能够按照上面的方式解决。生成的.dll文件,能够到相应的Debug里面去找。

第四部分:手把手教你把C语言的MELP语音压缩算法改成dll形式

一、首先网上搜索melp C,能够下载到美国军方标准的MELP开源的C代码。具体网址就不提供了。

二、打开VS2010(个人是英文版的),New Project->选择VisualC++的win32 project,余下的部分就和第一部分有点重复了。本文的工程名字:FileMelp

三、因为阅读了该源代码不少次了,了解了MELP算法的结构,以及帧的结构。编写了几个函数,方便调用。

四、回到第2步,右击工程名字,添加已有文件,把MELP解压缩后的文件都添加进来。

五、在melp.h文件最底部,加入以下的头部,方便生成dll的函数头部。

#ifndef LIB_H
#define LIB_H

extern _declspec(dllexport) void cmd_melp(int argc, char **argv);


extern _declspec(dllexport) void melp_encoder_ini();

extern _declspec(dllexport) void melp_encoder(
	short speechIn720[],
	char result27[]);

extern _declspec(dllexport) void melp_encoder720s(
	short speechIn720s[],//best length=720
	int times,
	char result27s[]);

	
extern _declspec(dllexport) void melp_decoder_ini();
extern _declspec(dllexport) void melp_decoder(
	char inChar27[],
	short *speechOut720);
extern _declspec(dllexport) void melp_decoder27s(
	char inChar27s[],
	int times,
	short *speechOut720s);

/* 加入任意你想加入的函数定义*/
#endif
六、在melp.c的最底部,加入以下的函数体。
void cmd_melp(int argc, char **argv)
{
	main(argc,argv);
}


void byte36Tobyte27(char* in36,char*out27)
{
	/* because 6 bits of a byte was used, so we can delete such bits.
	do as follow:
	the first 3*9 bytes was the original bytes.
	the last 1*9 bytes,was adding to the head*/
	char*in=in36;
	char inTem;
	char*out=out27;

	/* copy the 3*9 bytes */
	int n=27;
	while(n--)
	{
		*out++=*in++;
	}

	/* return the output*/
	out=out27;
	n=9;
	while(n--)
	{
		inTem=*in++;
		*out=(*out)|((inTem&0x30)<<2);
		out++;
		*out=(*out)|((inTem&0x0C)<<4);
		out++;
		*out=(*out)|((inTem&0x03)<<6);
		out++;
	}
}

void byte27Tobyte36(char* in27,char*out36)
{
		/* because 6 bits of a byte was used, so we can delete such bits.
	do as follow:
	the first 3*9 bytes was the original bytes.
	the last 1*9 bytes,was adding to the head*/
	char*in=in27;
	char inTem;
	char*out=out36;

	/* copy the 3*9 bytes */
	int n=27;
	while(n--)
	{
		*out++=((*in++)&0x3F);//because the first 2 bits was useless,so we can preserve
	}

	/* return the output*/
	in=in27;
	n=9;
	while(n--)
	{
		inTem=(*in++)&0xC0;
		*out=0;
		*out=inTem>>2;
		inTem=(*in++)&0xC0;
		*out=(*out)|(inTem>>4);

		inTem=(*in++)&0xC0;
		*out=(*out)|(inTem>>6);
		out++;
	}
}

void melp_encoder_ini()
{
	melp_ana_init();
}

void melp_encoder(
	short speechIn720[],//best length=720
	char result27[])
{
	/*
	here we assume that the LengthSpeechIn%180=0;
	*/

    static struct melp_param melp_par;      /* melp parameters */
    unsigned int chbuf[CHSIZE];
	char bytes36[36];
	float speechIn180[180];
	int LengthSpeech=180;
	int LengthByte=9;
	short * inOriginal;
	float * in180;
	char *out36byte;
	int q=4;


	inOriginal=speechIn720;
	out36byte=bytes36;

	while(q--)
	{
		/* copy the original speech into speechIn180 */
		LengthSpeech=180;
		in180=speechIn180;
		while(LengthSpeech--)
		{
			*in180++=*inOriginal++;
		}

		melp_par.chptr=chbuf;
		melp_par.chbit=0;

		/* do melp_ana */
		melp_ana(speechIn180,&melp_par);


		/* copy out */
		LengthByte=9;
		melp_par.chptr=chbuf;
		chbuf[0]=chbuf[0]-0x8000;
		while(LengthByte--)
		{
			*out36byte++=*(melp_par.chptr++);
		}
	}

	/* because only 6bits of a byte was used, so we can delete such usless bits. */
	byte36Tobyte27(bytes36,result27);

}



void melp_encoder720s(
	short speechIn720s[],//best length=720
	int times,
	char result27s[])
{
		
	short*in=speechIn720s;
	char*out=result27s;
	int i=times;
	while(i--)
	{
		melp_encoder(in,out);
		in+=720;
		out+=27;
	}
}

void melp_decoder_ini()
{
	melp_syn_init();
}

void melp_decoder(
	char inChar27[],
	short *speechOut720)//best length=180;else the same)
{

    static struct melp_param melp_par;      /* melp parameters */
    unsigned int chbuf[CHSIZE];
	char inChar36[36];
	float speechOut180[180];
	int LengthSpeech=180;
	int LengthBit=9;
	short * OutOriginal;
	float * Out180;
	unsigned int *in9s;
	char *inOriginal;

	int q=4;

	byte27Tobyte36(inChar27,inChar36);
	inOriginal=inChar36;
	OutOriginal=speechOut720;

	while(q--)
	{
		/* copy the original speech into speechIn180 */
		LengthBit=9;
		in9s=chbuf;
		while(LengthBit--)
		{
			*in9s++=*inOriginal++;
		}

		melp_par.chptr=chbuf;
		melp_par.chbit=0;
		chbuf[0]=chbuf[0]+0x8000;
		/* do melp_syn */
		melp_syn(&melp_par,speechOut180);


		/* copy out */
		LengthSpeech=180;
		Out180=speechOut180;
		while(LengthSpeech--)
		{
			*OutOriginal++=*Out180++;
		}
	}

}



/*  解码27长度的倍数 */
void melp_decoder27s(
	char inChar27s[],
	int times,
	short *speechOut720s)
{
	char*in=inChar27s;
	short*out=speechOut720s;
	int i=times;
	while(i--)
	{
		melp_decoder(in,out);
		in+=27;
		out+=720;
	}
}
实现相应的功能,同时要调整melp.h在melp.c中的位置,通常是在那一堆.h文件中,放置到最后面一行。

七、调试dll代码的过程,能够参加我上面的博客。生成后代码,就能够用在你想要的C#里面了。我在C#里面调用的方式以下。其中生成的FileMelp.dll改为了Melp.dll名字,如何添加到C#部分,详细见上面的部分。这样就能够运行了。

#region 须要的外部函数

        [DllImport("Melp.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        extern static void melp_encoder_ini();


        [DllImport("Melp.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        extern static void melp_encoder(
            Int16[] speechIn720,
            byte[] result27
            );

        [DllImport("Melp.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        extern static void melp_encoder720s(
            Int16[] speechIn720s,
            int times,
            byte[] result27s
            );

        [DllImport("Melp.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        extern static void melp_decoder_ini();


        [DllImport("Melp.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        extern static void melp_decoder(
            byte[] in27,
            Int16[] speechOut720
            );

        [DllImport("Melp.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        extern static void melp_decoder27s(
            byte[] in27s,
            int times,
            Int16[] speechOut720s
            );
        #endregion
相关文章
相关标签/搜索