c#调用C++写的dll导出类,如何实现
网上看了一些都是调用c++写函数
能不能实现c#使用c++写的类
各位高手请赐教
[解决办法]
可以……
[解决办法]
把类的指针给暴露出来,然后需要用的时候,传回C++的接口函数就可以了。
你根本就不用管这个类在C++里面是怎么定义的,也最好不要知道,如果不得不需要知道的话,那就请重新设计……
[解决办法]
类的有一个成员函数,是返回这个类的指针,那么在C#里面就是一个INTPTR,它是什么你不用管。
然后C++文件里面再定义几个函数,专门用于处理这个类的对像的操作,参数就是类对像的指针。这样你在C#层调用C++的这个函数,并将准备好的类对像的指针传回去就好了。
这种方法,安全,方便,而且……你那些查到的使用C++函数的方法,就可以用得到了。
当然了,暴露出整个C++类的定义也是可以的,不过那样要进行一次全结构定义复制,涉及到类型转换,很麻烦,而且不安全,最好不要这么做。
[解决办法]
P/Invoke?
[解决办法]
再用C++写一个DLL,在这个DLL中导入另一个DLL的导出类,再定义一些导出函数给C#调用。
[解决办法]
[解决办法]
LZ,奇迹来了,给分吧。。呵呵
贴上自己写过的东西,主要内容包含:在C++创—LL,以及使用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
[解决办法]
顶一下 接个分
[解决办法]
[解决办法]
up
[解决办法]
[解决办法]
[解决办法]
学习下
[解决办法]
[解决办法]
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#定义一样相同的就可以互相使用了。
[解决办法]
哎,学习一下。。。