大型的组件库为什么都用到了预处理
答案:2 悬赏:80 手机版
解决时间 2021-02-13 21:12
- 提问者网友:别再叽里呱啦
- 2021-02-13 03:57
大型的组件库为什么都用到了预处理
最佳答案
- 五星知识达人网友:猎心人
- 2021-02-13 05:09
不一定
stdio.h 只是你要使用stdio里面的函数或者宏定义的时候才需要包含。
如果你程序实现的功能 与这个头文件无关 那就不用包括了
一个简单的例子。如果你的程序 仅仅是与其它程序通信的,不需要任何输入输出,那么就不需要stdio,
不过 这很少见。大多数 仅仅是为了调试 也会加上stdio的。
stdio.h 只是你要使用stdio里面的函数或者宏定义的时候才需要包含。
如果你程序实现的功能 与这个头文件无关 那就不用包括了
一个简单的例子。如果你的程序 仅仅是与其它程序通信的,不需要任何输入输出,那么就不需要stdio,
不过 这很少见。大多数 仅仅是为了调试 也会加上stdio的。
全部回答
- 1楼网友:山有枢
- 2021-02-13 05:23
第一步,我先从简单的调用出发,定义了一个简单的函数,该函数仅仅实现一个整数加法求和:
libexport_api int mysum(int a,int b){ return a+b;}
c# 导入定义:
public class refcomm
{
[dllimport("libencrypt.dll",
entrypoint=" mysum ",
charset=charset.auto,callingconvention=callingconvention.stdcall)]
public static extern int mysum (int a,int b);
}
在c#中调用测试:
int isum = refcomm.mysum(,);
运行查看结果isum为5,调用正确。第一步试验完成,说明在c#中能够调用自定义的动态链接库函数。
第二步,我定义了字符串操作的函数(简单起见,还是采用前面的函数名),返回结果为字符串:
libexport_api char *mysum(char *a,char *b){sprintf(b,"%s",a); return a;}
c# 导入定义:
public class refcomm
{
[dllimport("libencrypt.dll",
entrypoint=" mysum ",
charset=charset.auto,
callingconvention=callingconvention.stdcall)]
public static extern string mysum (string a, string b);
}
在c#中调用测试:
string strdest="";
string strtmp= refcomm.mysum("45", strdest);
运行查看结果 strtmp 为"45",但是strdest为空。我修改动态链接库实现,返回结果为串b:
libexport_api char *mysum(char *a,char *b){sprintf(b,"%s",a) return b;}
修改 c# 导入定义,将串b修改为ref方式:
public class refcomm
{
[dllimport("libencrypt.dll",
entrypoint=" mysum ",
charset=charset.auto,callingconvention=callingconvention.stdcall)]
public static extern string mysum (string a, ref string b);
}
在c#中再调用测试:
string strdest="";
string strtmp= refcomm.mysum("45", ref strdest);
运行查看结果 strtmp 和 strdest 均不对,含不可见字符。再修改 c# 导入定义,将charset从auto修改为ansi:
public class refcomm
{
[dllimport("libencrypt.dll",
entrypoint=" mysum ",
charset=charset.ansi,callingconvention=callingconvention.stdcall)]
public static extern string mysum (string a, string b);
}
在c#中再调用测试:
string strdest="";
string strtmp= refcomm. mysum("45", ref strdest);
运行查看结果 strtmp 为"45",但是串 strdest 没有赋值。第二步实现函数返回串,但是在函数出口参数中没能进行输出。再次修改 c# 导入定义,将串b修改为引用(ref):
public class refcomm
{
[dllimport("libencrypt.dll",
entrypoint=" mysum ",
charset=charset.ansi,callingconvention=callingconvention.stdcall)]
public static extern string mysum (string a, ref string b);
}
运行时调用失败,不能继续执行。
第三步,修改动态链接库实现,将b修改为双重指针:
libexport_api char *mysum(char *a,char **b){sprintf((*b),"%s",a); return *b;}
c#导入定义:
public class refcomm
{
[dllimport("libencrypt.dll",
entrypoint=" mysum ",
charset=charset.ansi,callingconvention=callingconvention.stdcall)]
public static extern string mysum (string a, ref string b);
}
在c#中调用测试:
string strdest="";
string strtmp= refcomm. mysum("45", ref strdest);
运行查看结果 strtmp 和 strdest 均为"45",调用正确。第三步实现了函数出口参数正确输出结果。
第四步,修改动态链接库实现,实现整数参数的输出:
libexport_api int mysum(int a,int b,int *c){ *c=a+b; return *c;}
c#导入的定义:
public class refcomm
{
[dllimport("libencrypt.dll",
entrypoint=" mysum ",
charset=charset.ansi,callingconvention=callingconvention.stdcall)]
public static extern int mysum (int a, int b,ref int c);
}
在c#中调用测试:
int c=0;
int isum= refcomm. mysum(,, ref c);
运行查看结果isum 和c均为5,调用正确。
经过以上几个步骤的试验,基本掌握了如何定义动态库函数以及如何在 c# 定义导入,有此基础,很快我实现了变长加密函数在 c# 中的调用,至此目标实现。
三、结论
在 c# 中调用 c++ 编写的动态链接库函数,如果需要出口参数输出,则需要使用指针,对于字符串,则需要使用双重指针,对于 c# 的导入定义,则需要使用引用(ref)定义。
对于函数返回值,c# 导入定义和 c++ 动态库函数声明定义需要保持一致,否则会出现函数调用失败。定义导入时,一定注意 charset 和 callingconvention 参数,否则导致调用失败或结果异常。运行时,动态链接库放在 c# 程序的目录下即可,我这里是一个 c# 的动态链接库,两个动态链接库就在同一个目录下运行。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯