
c#中怎样运行调用的dll文件
2019-03-12 17:01:43
微信公开课小程序热门讨论「c#中怎样运行调用的dll文件」最新回复-动态链接库函数的声明动态链接库函数使用前必须声明,相对于VB,C#函数声明显得更加罗嗦,前者通过ApiViewer粘贴以后,可以直接使用,而后者则需要对参数作些额外的变化工作。动态链接库函数声明部分一般由下列两部分组成,一是函数名或索引号,二是动态链接库的文件名。譬如,你想调用User32.DLL中的MessageBox函数,我们必须指明函数的名字MessageBoxA或MessageBoxW,以及库名字User32.dll,我们知道Win32API对每一个涉及字符串和字符的函数一般都存在两个版本,单字节字符的ANSI版本和双字节字符的UNICODE版本。下面是一个调用API函数的例子:[DllImport(KERNEL32.DLL,EntryPoint=MoveFileW,SetLastError=true,CharSet=CharSet.Unicode,ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]publicstaticexternboolMoveFile(Stringsrc,Stringdst);其中入口点EntryPoint标识函数在动态链接库的入口位置,在一个受管辖的工程中,目标函数的原始名字和序号入口点不仅标识一个跨越互操作界限的函数。而且,你还可以把这个入口点映射为一个不同的名字,也就是对函数进行重命名。重命名可以给调用函数带来种种便利,通过重命名,一方面我们不用为函数的大小写伤透脑筋,同时它也可以保证与已有的命名规则保持一致,允许带有不同参数类型的函数共存,更重要的是它简化了对ANSI和Unicode版本的调用。CharSet用于标识函数调用所采用的是Unicode或是ANSI版本,ExactSpelling=false将告诉编译器,让编译器决定使用Unicode或者是Ansi版本。其它的参数请参考MSDN在线帮助.在C#中,你可以在EntryPoint域通过名字和序号声明一个动态链接库函数,如果在方法定义中使用的函数名与DLL入口点相同,你不需要在EntryPoint域显示声明函数。否则,你必须使用下列属性格式指示一个名字和序号。[DllImport(dllname,EntryPoint=Functionname)][DllImport(dllname,EntryPoint=#123)]值得注意的是,你必须在数字序号前加“#”下面是一个用MsgBox替换MessageBox名字的例子:[C#]usingSystem.Runtime.InteropServices;publicclassWin32{[DllImport(user32.dll,EntryPoint=MessageBox)]publicstaticexternintMsgBox(inthWnd,Stringtext,Stringcaption,uinttype);}许多受管辖的动态链接库函数期望你能够传递一个复杂的参数类型给函数,譬如一个用户定义的结构类型成员或者受管辖代码定义的一个类成员,这时你必须提供额外的信息格式化这个类型,以保持参数原有的布局和对齐。C#提供了一个StructLayoutAttribute类,通过它你可以定义自己的格式化类型,在受管辖代码中,格式化类型是一个用StructLayoutAttribute说明的结构或类成员,通过它能够保证其内部成员预期的布局信息。布局的选项共有三种:布局选项描述LayoutKind.Automatic为了提高效率允许运行态对类型成员重新排序。注意:永远不要使用这个选项来调用不受管辖的动态链接库函数。LayoutKind.Explicit对每个域按照FieldOffset属性对类型成员排序LayoutKind.Sequential对出现在受管辖类型定义地方的不受管辖内存中的类型成员进行排序。传递结构成员下面的例子说明如何在受管辖代码中定义一个点和矩形类型,并作为一个参数传递给User32.dll库中的PtInRect函数,函数的不受管辖原型声明如下:BOOLPtInRect(constRECT*lprc,POINTpt);注意你必须通过引用传递Rect结构参数,因为函数需要一个Rect的结构指针。[C#]usingSystem.Runtime.InteropServices;[StructLayout(LayoutKind.Sequential)]publicstructPoint{publicintx;publicinty;}[StructLayout(LayoutKind.Explicit]publicstructRect{[FieldOffset(0)]publicintleft;[FieldOffset(4)]publicinttop;[FieldOffset(8)]publicintright;[FieldOffset(12)]publicintbottom;}classWin32API{[DllImport(User32.dll)]publicstaticexternBoolPtInRect(refRectr,Pointp);}类似你可以调用GetSystemInfo函数获得系统信息:?usingSystem.Runtime.InteropServices;[StructLayout(LayoutKind.Sequential)]publicstructSYSTEM_INFO{publicuintdwOemId;publicuintdwPageSize;publicuintlpMinimumApplicationAddress;publicuintlpMaximumApplicationAddress;publicuintdwActiveProcessorMask;publicuintdwNumberOfProcessors;publicuintdwProcessorType;publicuintdwAllocationGranularity;publicuintdwProcessorLevel;publicuintdwProcessorRevision;}[DllImport(kernel32)]staticexternvoidGetSystemInfo(refSYSTEM_INFOpSI);SYSTEM_INFOpSI=newSYSTEM_INFO();GetSystemInfo(refpSI);类成员的传递同样只要类具有一个固定的类成员布局,你也可以传递一个类成员给一个不受管辖的动态链接库函数,下面的例子主要说明如何传递一个sequential顺序定义的MySystemTime类给User32.dll的GetSystemTime函数,函数用C/C++调用规范如下:voidGetSystemTime(SYSTEMTIME*SystemTime);不像传值类型,类总是通过引用传递参数.[C#][StructLayout(LayoutKind.Sequential)]publicclassMySystemTime{publicushortwYear;publicushortwMonth;publicushortwDayOfWeek;publicushortwDay;publicushortwHour;publicushortwMinute;publicushortwSecond;publicushortwMilliseconds;}classWin32API{[DllImport(User32.dll)]publicstaticexternvoidGetSystemTime(MySystemTimest);}回调函数的传递:从受管辖的代码中调用大多数动态链接库函数,你只需创建一个受管辖的函数定义,然后调用它即可,这个过程非常直接。如果一个动态链接库函数需要一个函数指针作为参数,你还需要做以下几步:首先,你必须参考有关这个函数的文档,确定这个函数是否需要一个回调;第二,你必须在受管辖代码中创建一个回调函数;最后,你可以把指向这个函数的指针作为一个参数创递给DLL函数,.回调函数及其实现:回调函数经常用在任务需要重复执行的场合,譬如用于枚举函数,譬如Win32API中的EnumFontFamilies(字体枚举),EnumPrinters(打印机),EnumWindows(窗口枚举)函数.下面以窗口枚举为例,谈谈如何通过调用EnumWindow函数遍历系统中存在的所有窗口分下面几个步骤:1.在实现调用前先参考函数的声明BOOLEnumWindows(WNDENUMPROClpEnumFunc,LPARMAMIParam)显然这个函数需要一个回调函数地址作为参数.2.创建一个受管辖的回调函数,这个例子声明为代表类型(delegate),也就是我们所说的回调,它带有两个参数hwnd和lparam,第一个参数是一个窗口句柄,第二个参数由应用程序定义,两个参数均为整形。当这个回调函数返回一个非零值时,标示执行成功,零则暗示失败,这个例子总是返回True值,以便持续枚举。3.最后创建以代表对象(delegate),并把它作为一个参数传递给EnumWindows函数,平台会自动地把代表转化成函数能够识别的回调格式。[C#]usingSystem;usingSystem.Runtime.InteropServices;publicdelegateboolCallBack(inthwnd,intlParam);publicclassEnumReportApp{[DllImport(user32)]publicstaticexternintEnumWindows(CallBackx,inty);publicstaticvoidMain(){CallBackmyCallBack=newCallBack(EnumReportApp.Report);EnumWindows(myCallBack,0);}publicstaticboolReport(inthwnd,intlParam){Console.Write(窗口句柄为);Console.WriteLine(hwnd);returntrue;}}指针类型参数传递:在WindowsAPI函数调用时,大部分函数采用指针传递参数,对一个结构变量指针,我们除了使用上面的类和结构方法传递参数之外,我们有时还可以采用数组传递参数。下面这个函数通过调用GetUserName获得用户名BOOLGetUserName(LPTSTRlpBuffer,//用户名缓冲区LPDWORDnSize//存放缓冲区大小的地址指针);[DllImport(Advapi32.dll,EntryPoint=GetComputerName,ExactSpelling=false,SetLastError=true)]staticexternboolGetComputerName([MarshalAs(UnmanagedType.LPArray)]byte[]lpBuffer,[MarshalAs(UnmanagedType.LPArray)]Int32[]nSize);这个函数接受两个参数,char*和int*,因为你必须分配一个字符串缓冲区以接受字符串指针,你可以使用String类代替这个参数类型,当然你还可以声明一个字节数组传递ANSI字符串,同样你也可以声明一个只有一个元素的长整型数组,使用数组名作为第二个参数。上面的函数可以调用如下:byte[]str=newbyte[20];Int32[]len=newInt32[1];len[0]=20;GetComputerName(str,len);MessageBox.Show(System.Text.Encoding.ASCII.GetString(str));最后需要提醒的是,每一种方法使用前必须在文件头加上:usingSystem.Runtime.InteropServices;
你想表达什么?运行dll文件?还是调用里面的方法? 更多有关「c#中怎样运行调用的dll文件」的疑问请扫码关注微信公开课+小程序!
你想表达什么?运行dll文件?还是调用里面的方法? 更多有关「c#中怎样运行调用的dll文件」的疑问请扫码关注微信公开课+小程序!
标签:微信公开课,小程序

「c#中怎样运行调用的dll文件」热议话题订阅
方法1:微信扫描微信公开课小程序码即可订阅热议话题「c#中怎样运行调用的dll文件」
方法2:微信搜索微信公开课小程序名称进入,即可订阅热议话题「c#中怎样运行调用的dll文件」
方法3:微信网页访问即速商店,长按识别微信公开课小程序码即可订阅热议话题「c#中怎样运行调用的dll文件」
微信公开课小程序热议话题「c#中怎样运行调用的dll文件」由微信公开课原创摘录于微信小程序商店shop.jisuapp.cn,转载请注明出处。
微信公开课热议话题「c#中怎样运行调用的dll文件」由微信公开课开发者向微信用户提供,并对本服务内容、数据资料及其运营行为等真实性、合法性及有效性承担全部责任。
微信公开课小程序
更新时间:2019-03-12 17:01:43
>
__methodCallerx27;ofundefined
>-404011cloudfunctionexecutionerror
>,请补充选择商家自营-预付卡销售-发行方类目,并在基础信息处申请该类目,通过
>:host在模拟器中显示无效
>:请在小程序服务页面上架正式(非测试)内容或商品后重新提交审核
>.net 微信小程序 上传图片
>'setTimeout'的问题
>‘三朵里熙SPA主题减压空间’为什么搜索关键词‘三朵里‘搜不到
>‘扫普通链接二维码打开小程序‘中设置为体验版,扫码打开是线上版本
>“cloudfunctions**indexjs”gitignore
>“NO ULINK DEVICE FOUND”是怎么回事
>“万马掌上校园”的类目审核
>“上线了”公司开发的微信小程序怎么样?
>“产品是否一定需要条形码”
>