• 非托管代码中调用托管代码


    托管类库(CSharp):
     1 using System;
     2 
     3 namespace ManagedPerson
     4 {
     5     public class Person
     6     {
     7         private string _name;
     8         private DateTime _birthday;
     9 
    10         public Person(string name, DateTime birthday)
    11         {
    12             _name = name;
    13             _birthday = birthday;
    14         }
    15 
    16         public uint Age
    17         {
    18             get
    19             {
    20                 DateTime now = DateTime.Now;
    21                 int age = now.Year - _birthday.Year;
    22                 if (_birthday.Month > now.Month ||
    23                     (_birthday.Month == now.Month && _birthday.Day > now.Day))
    24                 {
    25                     --age;
    26                 }
    27 
    28                 return (uint) age;
    29             }
    30         }
    31 
    32         public string Birthdaystr => _birthday.ToShortDateString();
    33 
    34         public DateTime Birthday => _birthday;
    35     }
    36 }
    C++/CLI包装类库(Managed C++):
     1 #pragma once
     2 
     3 #ifdef CLIPERSON_EXPORTS
     4 #define CLIPERSON_API __declspec(dllexport)
     5 #else
     6 #define CLIPERSON_API __declspec(dllimport)
     7 #endif
     8 
     9 #include <string>
    10 #include <Windows.h>
    11 
    12 using namespace std;
    13 
    14 class CLIPERSON_API CPerson
    15 {
    16 public:
    17     CPerson(string name, const SYSTEMTIME *birthday);
    18     virtual ~CPerson();
    19 
    20     unsigned int getAge() const;
    21     string getBirthdaystr() const;
    22     SYSTEMTIME getBirthday() const;
    23 
    24 private:
    25     void *clrPerson;
    26 };
     1 // CLIPerson.cpp: 定义 DLL 应用程序的导出函数。
     2 //
     3 
     4 #include "stdafx.h"
     5 #include "CLIPerson.h"
     6 #include <vcclr.h>
     7 
     8 using namespace System;
     9 using namespace Runtime::InteropServices;
    10 using namespace ManagedPerson;
    11 
    12 CPerson::CPerson(string name, const SYSTEMTIME * birthday)
    13 {
    14     DateTime ^datetime = gcnew DateTime(birthday->wYear, birthday->wMonth, birthday->wDay);
    15 
    16     //int nu = strlen(name.c_str());
    17     //int n = (size_t)MultiByteToWideChar(CP_ACP, 0, (const char *)name.c_str(), (int)nu, NULL, 0);
    18     //wchar_t *pwstr = new wchar_t[n];
    19     //MultiByteToWideChar(CP_ACP, 0, (const char *)name.c_str(), (int)nu, pwstr, (int)n);
    20     //String ^str = gcnew String(pwstr);
    21     //delete []pwstr;
    22 
    23     String ^str = gcnew String(name.c_str());
    24 
    25     Person ^person = gcnew Person(str, *datetime);
    26     // managed type conversion into unmanaged pointer is not allowed.
    27     // we can use gcroot<> wrapper.
    28     gcroot<Person ^> *pp = new gcroot<Person ^>(person);
    29     clrPerson = static_cast<void *>(pp);
    30 }
    31 
    32 CPerson::~CPerson()
    33 {
    34     if (clrPerson)
    35     {
    36         gcroot<Person ^> *pp = static_cast<gcroot<Person ^> *>(clrPerson);
    37         delete pp;
    38 
    39         clrPerson = 0;
    40     }
    41 }
    42 
    43 unsigned int CPerson::getAge() const
    44 {
    45     if (clrPerson != 0)
    46     {
    47         gcroot<Person ^> *pp = static_cast<gcroot<Person ^> *>(clrPerson);
    48         return ((Person ^)*pp)->Age;
    49     }
    50 
    51     return 0;
    52 }
    53 
    54 string CPerson::getBirthdaystr() const
    55 {
    56     string strage;
    57     if (clrPerson != 0)
    58     {
    59         gcroot<Person ^> *pp = static_cast<gcroot<Person ^> *>(clrPerson);
    60         strage = (const char *)Marshal::StringToHGlobalAnsi(((Person ^)*pp)->Birthdaystr).ToPointer();
    61     }
    62 
    63     return strage;
    64 }
    65 
    66 SYSTEMTIME CPerson::getBirthday() const
    67 {
    68     SYSTEMTIME st;
    69     if (clrPerson != 0)
    70     {
    71         gcroot<Person ^> *pp = static_cast<gcroot<Person ^> *>(clrPerson);
    72         DateTime dt = ((Person ^)*pp)->Birthday;
    73         st.wYear = dt.Year;
    74         st.wMonth = dt.Month;
    75         st.wDay = dt.Day;
    76     }
    77 
    78     return st;
    79 }

    此处需要特别注意的地方是Dll入口点不可以编译为MSIL,详细信息:https://msdn.microsoft.com/zh-cn/library/ccthbfk8(v=vs.100).aspx

     1 // dllmain.cpp : 定义 DLL 应用程序的入口点。
     2 #include "stdafx.h"
     3 
     4 #pragma unmanaged
     5 BOOL APIENTRY DllMain( HMODULE hModule,
     6                        DWORD  ul_reason_for_call,
     7                        LPVOID lpReserved
     8                      )
     9 {
    10     switch (ul_reason_for_call)
    11     {
    12     case DLL_PROCESS_ATTACH:
    13     case DLL_THREAD_ATTACH:
    14     case DLL_THREAD_DETACH:
    15     case DLL_PROCESS_DETACH:
    16         break;
    17     }
    18     return TRUE;
    19 }
    传统C++引入Library并测试:
     1 // main.cpp: 定义控制台应用程序的入口点。
     2 //
     3 
     4 #include "stdafx.h"
     5 #include "CLIPerson.h"
     6 #include <iostream>
     7 
     8 using namespace std;
     9 
    10 int main()
    11 {
    12     SYSTEMTIME st = { 0 };
    13     const char *name = "native call managed code";
    14 
    15     st.wYear = 1975;
    16     st.wMonth = 8;
    17     st.wDay = 15;
    18 
    19     CPerson person(name, &st);
    20 
    21     cout << name << ":" << endl;
    22     cout << "age:" << person.getAge() << endl;
    23     cout << "birthday:" << person.getBirthdaystr().c_str() << endl;
    24 
    25     system("pause");
    26 
    27     return 0;
    28 }

  • 相关阅读:
    指针
    const
    指针数组和指向数组的指针
    extjs初探之由浅入深目录
    ie6字体设置13px引发的问题
    在IAR下通过Jlink将程序直接下载到Flash指定地址
    提高C语言程序运行稳定性的方法
    C/C++编程习惯
    释放QQ占用的C盘空间
    非阻塞算法思想在关系数据库应用程序开发中的使用
  • 原文地址:https://www.cnblogs.com/linxmouse/p/8707900.html
Copyright © 2020-2023  润新知