How C + + invokes DLL developed by C #

Source: Internet
Author: User
Tags response code win32

Reprint Http://www.cnblogs.com/huangmianwu/p/6145044.html

Preface C++The program you write is unmanaged code, and C # writes a program that is managed code. While managed code offers many advantages that other development platforms do not, the CLR provides mechanisms that allow both managed and unmanaged code to be included in the application because of the many uses of unmanaged code written by the previous system and historical versions. Specifically, there are three types: managed code can call unmanaged functions in a DLL. Through P/The invoke (Platform invoke) mechanism invokes functions in the DLL, such as Kernel32.dll. Managed code can use an existing COM component (server). Many companies have implemented a large number of unmanaged COM components. Using a type library from these components, you can create a managed assembly to describe the COM component. Managed code can access types in a managed assembly as if it were any other type. Managed types (servers) can be used by unmanaged code. Many existing unmanaged code requires the COM component to be provided to ensure that the code works correctly. Using managed code makes it easier to implement these components, avoiding all code having to deal with reference counts and interfaces. Like C .++invokes the DLL developed by C #. Some of the above text is from the CLR via C #, which is a bit more difficult to understand. It's just working. C++The experience of invoking the DLL developed by C #, which is the 3rd above. So I want to take this article to record the development of the steps and ideas. The subsequent time to the above 1, 2 points to fill up, forming a series of articles. Body1, writing a DLL in C # This DLL simply implements two functions: string concatenation and two number additions. First create the method interface: Add and join. The code is as follows: Copy code [GUID ("254d1fbc-416b-422f-ae39-c923e8803396")] Public InterfaceIcalc {[DispID (1)] BOOLADD (stringAstringB out intc); [DispID (2)] voidJoin (stringAstringB out stringc); Copy the code in order to introduce a more comprehensive description of the invocation of the method type, where the Add method return value is specifically defined as type bool, the result is output parameter outputs, int type; The Join method has no return value (void type), and the result is output by the output parameter, which is a string type. where the DispID attribute and the GUID attribute are required. DispID are numbered sequentially. The GUID is created as a tool--Create Guid-->Select 5th, copy (for VS2013) as shown: Next Create the Calc class that inherits the Icalc interface, implementing the Add and join methods, the code is as follows. You also need to create a GUID, as in the previous step. Copy code [Guid ("f963b111-39fa-499d-9172-6102c79bb6e5")][classinterface (classinterfacetype.none)] Public classCalc:icalc { Public BOOLADD (stringAstringB out intc) {intint_a; intInt_b; if(! Int32.TryParse (A, outint_a)) {C=0; return false; } if(! Int32.TryParse (b, outint_b)) {C=0; return false; } C= Int_a +Int_b; return true; } Public voidJoin (stringAstringB out stringc) {c= A +b; return ; The copy code also needs to set the "Make assembly COM Visible" and "Register for COM Interop" "Make assembly COM Visible" step: Project Properties--"Application" Item---"Assembly Information"-tick "make assembly COM visible" as shown in: "Register for COM Interop" setting Steps: Project Properties--"Generate" Item--tick "Register for COM Interop", as shown in: Note: This operation requires system administrator privileges, run as "Administrator" when starting VS, otherwise the Access denied error to registry key XXX Occurs when the solution is built. After the solution is built, a DLL and TLB two files are generated. This completes the C # end of the work. The next step is to generate a registry file from Regasm.exe for the consumer to register the DLL as a COM component. 2, registering the DLL as a COM component at native development because the check box "register for COM Interop" option is checked, so when the solution is built, the DLL is already registered as a COM component in the native, so the runtime does not need to be re-registered, but if it is running on another machine, The DLL needs to be registered as a COM component before it can be used. Here we generate the registry file through Regasm.exe for the consumer to register the DLL as a COM component (in fact, the GUID is imported into the registry). The script file is as follows: RegAsm E:\ Blog Park \unmanagecodecallmanagecode\calcclass\calcclass\bin\debug\calcclass.dllregasm e:\ Blog Park \ Unmanagecodecallmanagecode\calcclass\calcclass\bin\debug\calcclass.dll/tlb:CalcClass.tlbregasm e:\ Blog Park \unmanagecodecallmanagecode\calcclass\calcclass\bin\debug\calcclass.dll/Regfile:CalcClass.reg Note that the Regasm.exe version used is best aligned with the. NET framework version used by the development DLL. Run the script to generate the Calcclass.reg file. Run the file on another machine to register the COM component for normal use. The next question is how to encapsulate it as a COM component. 3, encapsulate the DLL as a COM component, create a new workspace, select Win32 Dynamic-Link Library, type is a simple DLL project. Copy the above generated DLL and TLB two files to the workspace file path. Add the following two lines of code to the DLL under the StdAfx.h header file: (The content needs to be changed based on the TLB file name and namespace) #import"calcclass.tlb"using namespaceCalcclass; Add the following method declaration in the CPP file (declared as an external function of the C-compile connection method), or you can create a header file to include in it. extern "C"_declspec (dllexport) BOOL Add (CharBChar* B,Long*c);extern "C"_declspec (dllexport)voidJoin (CharACharAChar*c); Two ways to implement a declaration: Copy code BOOL ADD (CharACharALong*c) {CoInitialize (NULL); Calcclass::icalcptr calcptr (__uuidof (Calc));//gets the GUID associated with the CalcVARIANT_BOOL ret = calcptr->Add (_bstr_t (a), _bstr_t (b), c); Calcptr-Release (); CoUninitialize (); if(ret = =-1 ) return 1; Else returnret;}voidJoin (CharBChar* B,Char*c) {CoInitialize (NULL); Calcclass::icalcptr calcptr (__uuidof (Calc));//gets the GUID associated with the CalcBSTR temp; Calcptr->join (_bstr_t (a), _bstr_t (b),&temp); strcpy (c, _com_util::convertbstrtostring (temp)); Calcptr-Release (); CoUninitialize (); Copy the code here to do two point description:1, for a brief introduction to the Variant_bool type:-1 indicates that true,0 represents false. (This really overturns our conventional understanding of the bool value.)2, C # out parameter converted to C + +must pass a pointer variable, that is, the parameter should be taken to refer to the operation, which is the essence of the output parameters. (You can use a TLB file reference call, or after the build reference to view the Tli or TLH file), the task of encapsulating the DLL as a COM component is completed successfully. Thus, C++can invoke a DLL written in C #. A demo example of the call is shown below. 4, call the Demo sample new workspace, select Win32 exe, type dialog box. The design interface is as follows, adding a button event onaddbtn and Onjoinbtn declaration method with the following code: TypeDef BOOL (* Add) (CharBChar* B,Long*c); typedefvoid(* Join) (CharBChar* B,Char*c); The Onaddbtn event response code is as follows: Copy codevoidccalccomdemodlg::onaddbtn () {//Todo:add your control notification handler code hereBOOL ret; Longresult; Chara[255]; Charb[255]; CString str_a; CString Str_b; GetDlgItem (IDC_EDIT1)-GetWindowText (str_a); GetDlgItem (IDC_EDIT2)-GetWindowText (Str_b); strcpy (a,str_a); strcpy (B,str_b); HINSTANCE Calc; Calc= LoadLibrary (TEXT ("CalcCom.dll")); if(NULL = =Calc) {MessageBox ("cant ' t find dll"); return; } Add _add= (ADD):: GetProcAddress (Calc,"ADD"); if(NULL = =_add) {MessageBox ("cant ' t find function"); return; } Else{ret= _add (a,b,&result); CString boxmsg; Boxmsg.format ("Reslut:%d\nmessage:%ld\n", Ret,result); MessageBox (BOXMSG); The Copy Code ONJOINBTN event response code is as follows: Copy codevoidccalccomdemodlg::onjoinbtn () {//Todo:add your control notification handler code here Chara[255]; Charb[255]; CString str_a; CString Str_b; GetDlgItem (IDC_EDIT1)-GetWindowText (str_a); GetDlgItem (IDC_EDIT2)-GetWindowText (Str_b); strcpy (a,str_a); strcpy (B,str_b); Charresult[255]; HINSTANCE Calc; Calc= LoadLibrary (TEXT ("CalcCom.dll")); if(NULL = =Calc) {MessageBox ("cant ' t find dll"); return; } Join _join= (Join):: GetProcAddress (Calc,"Join"); if(NULL = =_join) {MessageBox ("cant ' t find function"); return; } Else{_join (a,b,result); CString boxmsg; Boxmsg.format ("message:%s\n", result); MessageBox (BOXMSG); }} Copy the code here is LoadLibrary (TEXT ("CalcCom.dll") , default to the DLL under EXE execution path. So the generated COM component DLL is copied to the EXE execution path after the compilation is complete. Of course, you can also specify the path to the DLL directly. Run the program to verify that the DLL written in C # is successfully invoked. As shown in. The Add method invokes the result of the Join method call result attachment as the program source code. For reference only. http://Files.cnblogs.com/files/huangmianwu/unmanagecodecallmanagecode.rar

How C + + invokes DLL developed by C #

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.