首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

c#调用C++写的dll导出类,怎么实现

2012-06-15 
c#调用C++写的dll导出类,如何实现网上看了一些都是调用c++写函数能不能实现c#使用c++写的类各位高手请赐教

c#调用C++写的dll导出类,如何实现

网上看了一些都是调用c++写函数

能不能实现c#使用c++写的类

各位高手请赐教

[解决办法]
可以……
[解决办法]
把类的指针给暴露出来,然后需要用的时候,传回C++的接口函数就可以了。

你根本就不用管这个类在C++里面是怎么定义的,也最好不要知道,如果不得不需要知道的话,那就请重新设计……
[解决办法]
类的有一个成员函数,是返回这个类的指针,那么在C#里面就是一个INTPTR,它是什么你不用管。

然后C++文件里面再定义几个函数,专门用于处理这个类的对像的操作,参数就是类对像的指针。这样你在C#层调用C++的这个函数,并将准备好的类对像的指针传回去就好了。

这种方法,安全,方便,而且……你那些查到的使用C++函数的方法,就可以用得到了。

当然了,暴露出整个C++类的定义也是可以的,不过那样要进行一次全结构定义复制,涉及到类型转换,很麻烦,而且不安全,最好不要这么做。
[解决办法]
P/Invoke?
[解决办法]
再用C++写一个DLL,在这个DLL中导入另一个DLL的导出类,再定义一些导出函数给C#调用。
[解决办法]

探讨
把类的指针给暴露出来,然后需要用的时候,传回C++的接口函数就可以了。

你根本就不用管这个类在C++里面是怎么定义的,也最好不要知道,如果不得不需要知道的话,那就请重新设计……

[解决办法]
LZ,奇迹来了,给分吧。。呵呵

贴上自己写过的东西,主要内容包含:在C++创建DLL,以及使用C++或者C#分别调用DLL中的方法,环境VS2005。

VS2005中很多工程都可以生成DLL,例如atl,mfc,win32等等。选择Win32,步骤如下:
1:新建项目TestDLL,选择win32中的win32控制台应用程序,在“应用程序设置”中,选择“应用程序类型”为DLL,并将下方的附加选项勾上“空项目”,就可以了。 

2:添加一个C++类,这时vs2005会生成TestDLL.h和TestDLL.cpp的文件,在.h文件中,键入如下代码:
#define LIBEXPORT_API extern "C" __declspec(dllexport) 
LIBEXPORT_API int f( char * ch);//这是一个测试程序 

3:然后在.cpp文件中,必须加入DllMain函数以作为程序出口,并实现函数f:
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{//程序出口
return TRUE;


//函数的实现在这里
LIBEXPORT_API int f(char * ch)
{
return 88;


4:编译生成,就能得到与项目同名的TestDLL.dll。注意,生成的dll文件在外面的一个debug文件中。

接下来该怎么调用dll,分别在C++和C#做了调用。调用过程如下:
C++调用:
1:首先将dll文件加入工程,拷贝dll置于c++项目文件所在的目录。
2:调用代码
 typedef int (*TEST) (char * ch);//定义调用DLL函数的类型
 //下面是调用过程
 HINSTANCE hDLL; 
 TEST f;
 hDLL = LoadLibrary(_T("TestDLL.dll"));//加载动态链接库TestDLL.dll文件; 
 f = (TEST)GetProcAddress(hDLL,(LPCSTR)"f"); //调用的f函数
 int si ;
 si = f("abc");
FreeLibrary(hDLL);//卸载TestDLL.dll文件;
cout<<si;
 return 0;
3:结果——屏幕返回88,正确地调用了dll中的方法。 

C#调用:
1:将dll文件拷贝至C#执行文件所在目录,一般在/bin/debug目录下;
2:调用代码
 using System.Runtime.InteropServices;
 ... 
 ...
class CallDLL
{//使用一个类封装所有dll的函数
[DllImport("TestDLL.dll", EntryPoint = "f",
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]//指定dll访问入口
public static extern int f(string s);//定义调用dll中函数的类型
}
...
//使用dll中的函数
int m = CallDLL.f("mmm");
3:结果m的值正是88,操作成功。


[解决办法]
方法都可以调用了,类的定义道理是一样的


在C++中这样定义你的类
class LIBEXPORT_API YourClass
{
.....
}
[解决办法]
可以调用托管C++类,不能调用非托管C++类
[解决办法]

 添加引用

 [DllImport("XXXX.dll", CharSet = CharSet.Auto)] ''动态链接库
public static extern int XXXX(int XXXX); ''具体方法声明
[解决办法]
没看清楚,


你要调用c++里面的类啊,呵呵
[解决办法]
c#调用 c++的dll文件

http://blog.csdn.net/zhangzxy161723/archive/2009/04/28/4132853.aspx
[解决办法]
http://topic.csdn.net/u/20090430/17/5148f3de-9f7d-45b1-b5ba-2fcaf06baafc.html


[解决办法]
MARK,楼主可以搜一下C#调用ActiveDesktop的代码,据说那是个C++类,贴一点,仅供参考,内容过长,分多贴回了

这个是根据C++头文件搞的一些枚举

C# code
using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;namespace HKH.Common.System.ComImports{    #region ActiveDesktop Enums    //Defined in shlobj.h    // Flags for IActiveDesktop::GetWallpaperOptions()    //           IActiveDesktop::SetWallpaperOptions()    public enum WallpaperStyle    {        Center = 0,        Tile = 1,        Stretch = 2,        Max = 3    }    [Flags]    internal enum ItemState    {        Normal = 0x00000001,        FullScreen = 00000002,        Split = 0x00000004,        ValidSizeStateBits = Normal | Split | FullScreen,    // The set of IS_* state bits which define the "size" of the component - these bits are mutually exclusive.        ValidStateBits = Normal | Split | FullScreen | unchecked((int)0x80000000) | 0x40000000    // All of the currently defined IS_* bits.    }    internal enum ComponentType    {        HtmlDoc = 0,        Picture = 1,        WebSite = 2,        Control = 3,        CFHtml = 4,        Max = 4    }    //Flags for IActiveDesktop::AddDesktopItemWithUI()    internal enum DeskTopItemAddWithUI    {        Default = 0x00000000,        DisplaySubWizard = 0x00000001,        PositionItem = 0x00000002,    }    // Flags for IActiveDesktop::ApplyChanges()    [Flags]    internal enum ActiveDesktopApply    {        Save = 0x00000001,        HtmlGen = 0x00000002,        Refresh = 0x00000004,        All = Save | HtmlGen | Refresh,        Force = 0x00000008,        BufferedReferesh = 0x00000010,        DynamicReferesh = 0x00000020    }    // Flags for IActiveDesktop::ModifyComponent()    [Flags]    internal enum ComponentElement    {        Type = 0x00000001,        Checked = 0x00000002,        Dirty = 0x00000004,        NoScroll = 0x00000008,        Left = 0x00000010,        Top = 0x00000020,        Width = 0x00000040,        Height = 0x00000080,        ZIndex = 0x00000100,        Source = 0x00000200,        FriendlyName = 0x00000400,        SubscribedUrl = 0x00000800,        OriginalCSI = 0x00001000,        RestoredCSI = 0x00002000,        CurrentItemState = 0x00004000,        All = Type | Checked | Dirty | NoScroll | Left | Width | Height | ZIndex | Source | FriendlyName | Top |            SubscribedUrl | OriginalCSI | RestoredCSI | CurrentItemState    }    // Flags for IActiveDesktop::AddUrl()    [Flags]    internal enum AddUrl    {        Silent = 0x0001    }    #endregion}
[解决办法]

这个是另个一些需要的结构
C# code
using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;namespace HKH.Common.System.ComImports{    #region ActiveDesktop Structs    //Defined in shlobj.h    internal struct WallpaperOption    {        public int Size;            // size of this Structure. 8 = Marshal.SizeOf(WallpaperOption)        public WallpaperStyle Style;        // WPSTYLE_* mentioned above    }    internal struct ComponentOption    {        public int Size;            //Size of this structure, 12 = Marshal.SizeOf(ComponentOption)        [MarshalAs(UnmanagedType.Bool)]        public bool EnableComponents;        //Enable components?        [MarshalAs(UnmanagedType.Bool)]        public bool EnableActiveDesktop;    // Active desktop enabled ?    }    internal struct ComponentPosition    {        public const int COMPONENT_TOP = 0x3FFFFFFF;        public const int COMPONENT_DEFAULT_LEFT = 0xFFFF;        public const int COMPONENT_DEFAULT_TOP = 0xFFFF;        public int Size;            //Size of this structure        public int Left;            //Left of top-left corner in screen co-ordinates.        public int Top;                //Top of top-left corner in screen co-ordinates.        public int Width;            // Width in pixels.                public int Height;            // Height in pixels.        public int ZIndex;            // Indicates the Z-order of the component.        [MarshalAs(UnmanagedType.Bool)]        public bool CanResize;            // Is the component resizeable?        [MarshalAs(UnmanagedType.Bool)]        public bool CanResizeX;            // Resizeable in X-direction?        [MarshalAs(UnmanagedType.Bool)]        public bool CanResizeY;            // Resizeable in Y-direction?        public int PreferredLeftPercent;    //Left of top-left corner as percent of screen width        public int PreferredTopPercent;        //Top of top-left corner as percent of screen height    }    internal struct ComponentStateInfo    {        public int Size;            // Size of this structure.        public int Left;            // Left of the top-left corner in screen co-ordinates.        public int Top;                // Top of top-left corner in screen co-ordinates.        public int Width;            // Width in pixels.        public int Height;            // Height in pixels.        public ItemState ItemState;        // State of the component (full-screen mode or split-screen or normal state.    }    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]    internal struct Component    {        private const int INTERNET_MAX_URL_LENGTH = 2084; // =         public int Size;            //Size of this structure        public int ID;                //Reserved: Set it always to zero.        public ComponentType iComponentType;    //One of COMP_TYPE_*        [MarshalAs(UnmanagedType.Bool)]        public bool Checked;            // Is this component enabled?        [MarshalAs(UnmanagedType.Bool)]        public bool Dirty;            // Had the component been modified and not yet saved to disk?        [MarshalAs(UnmanagedType.Bool)]        public bool NoScroll;            // Is the component scrollable?        public ComponentPosition Position;    // Width, height etc.,        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]        public string FriendlyName;        // Friendly name of component.        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = INTERNET_MAX_URL_LENGTH)]        public string Source;            //URL of the component.        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = INTERNET_MAX_URL_LENGTH)]        public string SubscribedURL;        //Subscrined URL        //New fields are added below. Everything above here must exactly match the IE4COMPONENT Structure.        public ItemState ItemState;        // Current state of the Component.        public ComponentStateInfo OriginalCSI;    // Original state of the component when it was first added.        public ComponentStateInfo RestoredCSI;    // Restored state of the component.    }    #endregion} 


[解决办法]

这个就是我封得C#的类了,最下边是C++的接口到C#的ComImport映射,上边的两个方法是我用的

C# code
using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;namespace HKH.Common.System.ComImports{    public class ActiveDesktopUtil    {        private static readonly Guid CLSID_ActiveDesktop = new Guid("{75048700-EF1F-11D0-9888-006097DEACF9}");        private const char WHITESPACE = ' ';        private const string ENDOFCHARARRAY = "\0";        private ActiveDesktopUtil()        {        }        private static IActiveDesktop GetActiveDesktop()        {            Type typeActiveDesktop = Type.GetTypeFromCLSID(CLSID_ActiveDesktop);            return (IActiveDesktop)Activator.CreateInstance(typeActiveDesktop);        }        /// <summary>        /// Sets Active Desktop Wallpaper        /// </summary>        /// <param name="fileName">the full path of file to set as Wallpaper. If null, reset to default</param>        /// <param name="style"></param>        /// <param name="forceEnabled">indicates whether enable this setting.</param>        public static void SetActiveDesktopWallpaper(string fileName, WallpaperStyle style, bool forceEnabled)        {            IActiveDesktop activeDesktop = GetActiveDesktop();            WallpaperOption wallpaperOption = new WallpaperOption();            ComponentOption componentOption = new ComponentOption();            wallpaperOption.Size = Marshal.SizeOf(wallpaperOption);            wallpaperOption.Style = style;            componentOption.Size = Marshal.SizeOf(componentOption);            activeDesktop.GetDesktopItemOptions(ref componentOption, 0);            if (!componentOption.EnableActiveDesktop && forceEnabled)            {                componentOption.EnableActiveDesktop = true;                activeDesktop.SetDesktopItemOptions(ref componentOption, 0);            }            activeDesktop.SetWallpaperOptions(ref wallpaperOption, 0);            activeDesktop.SetWallpaper(fileName, 0);            activeDesktop.ApplyChanges(ActiveDesktopApply.All);        }        /// <summary>        /// Gets Active Desktop Wallpaper        /// </summary>        /// <returns></returns>        public static string GetActiveDesktopWallpaper()        {            IActiveDesktop activeDesktop = GetActiveDesktop();            WallpaperOption wallpaperOption = new WallpaperOption();            wallpaperOption.Size = Marshal.SizeOf(wallpaperOption);            string sFile = new string(WHITESPACE, 260);            activeDesktop.GetWallpaper(sFile, 260, 0);            activeDesktop.GetWallpaperOptions(ref wallpaperOption, 0);            int pos = sFile.IndexOf(ENDOFCHARARRAY);            if (pos > -1)            {                sFile = sFile.Substring(0, pos);            }            return sFile;        }    }    #region Internal Com Class Import    [ComImport(),Guid("F490EB00-1240-11D1-9888-006097DEACF9"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]    internal interface IActiveDesktop    {        void ApplyChanges(ActiveDesktopApply dwFlags);        void GetWallpaper([MarshalAs(UnmanagedType.LPWStr)]string pwszWallpaper, int cchWallpaper, int dwReserved);        void SetWallpaper([MarshalAs(UnmanagedType.LPWStr)]string pwszWallpaper, int dwReserved);        void GetWallpaperOptions(ref WallpaperOption pwpo, int dwReserved);        void SetWallpaperOptions([In]ref WallpaperOption pwpo, int dwReserved);        void GetPattern([MarshalAs(UnmanagedType.LPWStr)]string pwszPattern, int cchPattern, int dwReserved);        void SetPattern([MarshalAs(UnmanagedType.LPWStr)]string pwszPattern, int dwReserved);        void GetDesktopItemOptions(ref ComponentOption pco, int dwReserved);        void SetDesktopItemOptions([In]ref ComponentOption pco, int dwReserved);        void AddDesktopItem([In]ref Component pcomp, int dwReserved);        void AddDesktopItemWithUI(IntPtr hwnd, [In]ref Component pcomp, DeskTopItemAddWithUI dwFlags);        void ModifyDesktopItem([In]ref Component pcomp, ComponentElement dwFlags);        void RemoveDesktopItem([In]ref Component pcomp, int dwReserved);        void GetDesktopItemCount(out int lpiCount, int dwReserved);        void GetDesktopItem(int nComponent, ref Component pcomp, int dwReserved);        void GetDesktopItemByID(IntPtr dwID, ref Component pcomp, int dwReserved);        void GenerateDesktopItemHtml([MarshalAs(UnmanagedType.LPWStr)]string pwszFileName, [In]ref Component pcomp, int dwReserved);        void AddUrl(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)]string pszSource, [In] ref Component pcomp, AddUrl dwFlags);        void GetDesktopItemBySource([MarshalAs(UnmanagedType.LPWStr)]string pwszSource, ref Component pcomp, int dwReserved);    }    [ComImport(),Guid("75048700-EF1F-11D0-9888-006097DEACF9")]    internal class ActiveDesktop /* : IActiveDesktop */     {    }    #endregion} 


[解决办法]
不知道楼主的问题解决了没有
我也有楼主相似的问题

C/C++ code
struct CATInfo{  int catCount;  struct ClsInfo *ClsTable;  char *dstFolder;  char *srcFolder;  int docNum;  FILE *fpWL;  int right;  void*handle;};
[解决办法]
dllimport
[解决办法]
顶一下 接个分
[解决办法]
探讨
LZ,奇迹来了,给分吧。。呵呵

贴上自己写过的东西,主要内容包含:在C++创建DLL,以及使用C++或者C#分别调用DLL中的方法,环境VS2005。

VS2005中很多工程都可以生成DLL,例如atl,mfc,win32等等。选择Win32,步骤如下:
1:新建项目TestDLL,选择win32中的win32控制台应用程序,在“应用程序设置”中,选择“应用程序类型”为DLL,并将下方的附加选项勾上“空项目”,就可以了。

2:添加一个C++类,这时vs2005会…

[解决办法]
up
[解决办法]
探讨
不知道楼主的问题解决了没有
我也有楼主相似的问题
C/C++ codestructCATInfo
{intcatCount;structClsInfo*ClsTable;char*dstFolder;char*srcFolder;intdocNum;
FILE*fpWL;intright;void*handle;
};

请问这个结构怎么转换成C#,主要是FILE这个类,请高手们指点~~~

[解决办法]

[解决办法]
学习下
[解决办法]
探讨
引用:
不知道楼主的问题解决了没有
我也有楼主相似的问题
C/C++ codestructCATInfo
{intcatCount;structClsInfo*ClsTable;char*dstFolder;char*srcFolder;intdocNum;
FILE*fpWL;intright;void*handle;
};

请问这个结构怎么转换成C#,主要是FILE这个类,请高手们指点~~~


搜一下FILE这个结构的定义,使用StructLayout对它继续定义
一般来说系统的东西都会在shell.h, user.h,k…

[解决办法]
LZ执着精神值得钦佩啊。
我机器上现在没有C#的开发环境,所以没办法跟你拿出完整代码了,帮你顶顶吧。

顺便问一句,大家说了这么多方法,到底你现在的问题是什么?能具体描述一下嘛?
[解决办法]
http://blog.csdn.net/null1/archive/2009/03/03/3953155.aspx
[解决办法]
你可以换个思路啊。
其实用C++中的类,说到底还是使用它的共有方法。在C#中,你可以把C++中的使用到的所有方法封装成一个类,从而直接在C#下使用,怎么把C++中的方法在C#中调用我上面已经说过了。
哎,不知道怎么帮你,再帮你顶顶吧。
[解决办法]
楼主,还是自己动手试试吧,或许奇迹你自己就能创造的。

[解决办法]
//-------------头文件
#pragma once

class testclass
{
public:
testclass(void);
~testclass(void);
public:
WCHAR* GetName(void);
};
//-------------CPP
#include "StdAfx.h"
#include "testclass.h"

testclass::testclass(void)
{
}

testclass::~testclass(void)
{
}
WCHAR* testclass::GetName(void)
{
return NULL;
}

//--------------接口头文件
#pragma once

#include "testclass.h"

class Insertface
{
public:
Insertface(void);
~Insertface(void);
public:
void* CreateTextClass(void);
WCHAR* GetName(void *textClass);
BOOL DeleteTextClass(void *textClass);
};
//----------------------CPP
#include "StdAfx.h"
#include "Insertface.h"

Insertface::Insertface(void)
{
}

Insertface::~Insertface(void)
{
}
extern "C" _declspec(dllexport) void* Insertface::CreateTextClass(void)


{
testclass *p = new testclass();
return (void *)p;
}
extern "C" _declspec(dllexport) WCHAR* Insertface::GetName(void *textClass)
{
return ((testclass *)textClass)->GetName();
}
extern "C" _declspec(dllexport) BOOL Insertface::DeleteTextClass(void *textClass)
{
delete (testclass *)textClass;
return TRUE;
}

//----------------------C#
//C#代码我就不写了,在C#使用long类型来接受void *。指针就被C#记录了,在C++使用dllexport开放类的方法,这样C#就可以使用C++里的类。目前我是这样用的~不知道是不是您要的。。还有如果是C++定义的结构,C#定义一样相同的就可以互相使用了。

[解决办法]
哎,学习一下。。。

热点排行