楼上的兄弟姐妹们,方法都找到了。看下面: DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息。 DllImport属性应用于方法,要求最少要提供包含入口点的dll的名称。 DllImport的定义如下: [AttributeUsage(AttributeTargets.Method)] public class DllImportAttribute: System.Attribute { public DllImportAttribute(string dllName) {…} //定位参数为dllName public CallingConvention CallingConvention; //入口点调用约定 public CharSet CharSet; //入口点采用的字符接 public string EntryPoint; //入口点名称 public bool ExactSpelling; //是否必须与指示的入口点拼写完全一致,默认false public bool PreserveSig; //方法的签名是被保留还是被转换 public bool SetLastError; //FindLastError方法的返回值保存在这里 public string Value { get {…} } } 用法示例: [DllImport("kernel32")] private static extern long WritePrivateProfileString(string section,string key,string val,string filePath); 以上是用来写入ini文件的一个win32api。
//添加这个dll [DllImport("kernel32.dll")] public extern static int LoadLibraryEx(string lpLibFileName, int hFile, int dwFlags); //在调用自己的dll函数之前 DLLInvoke.LoadLibraryEx( System.IO.Path.Combine(AppDomain.CurrentDomain.SetupInformation.PrivateBinPath, "/*我的dll名称*/"), 0, 8 //LOAD_WITH_ALTERED_SEARCH_PATH );
<appSettings>
<add key="MyDLL" value="Your dll file url"/>
</appSettings>在其他项目里引用
ConfigurationManager.AppSettings["MyDLL"]
服务进程的path环境变量和桌面用户的不一样的。
DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息。
DllImport属性应用于方法,要求最少要提供包含入口点的dll的名称。
DllImport的定义如下:
[AttributeUsage(AttributeTargets.Method)]
public class DllImportAttribute: System.Attribute
{
public DllImportAttribute(string dllName) {…} //定位参数为dllName
public CallingConvention CallingConvention; //入口点调用约定
public CharSet CharSet; //入口点采用的字符接
public string EntryPoint; //入口点名称
public bool ExactSpelling; //是否必须与指示的入口点拼写完全一致,默认false
public bool PreserveSig; //方法的签名是被保留还是被转换
public bool SetLastError; //FindLastError方法的返回值保存在这里
public string Value { get {…} }
}
用法示例:
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section,string key,string val,string filePath);
以上是用来写入ini文件的一个win32api。
用此方式调用Win32API的数据类型对应:DWORD=int或uint,BOOL=bool,预定义常量=enum,结构=struct。DllImport会按照顺序自动去寻找的地方:
1、exe所在目录
2、System32目录
3、环境变量目录
所以只需要你把引用的DLL 拷贝到这三个目录下 就可以不用写路径了 或者可以这样server.MapPath(.\bin\*.dll)
web中的,同时也是应用程序中的
后来发现用[DllImport(@"C:\OJ\Bin\Judge.dll")]这样指定DLL的绝对路径就可以正常装载。
这个问题最常出现在使用第三方非托管DLL组件的时候,我的也同样是这时出的问题,Asp.Net Team的官方解决方案如下:
首先需要确认你引用了哪些组件,那些是托管的,哪些是非托管的.托管的很好办,直接被使用的需要引用,间接使用的需要拷贝到bin目录下.非托管的处理
会比较麻烦.实际上,你拷贝到bin没有任何帮助,因为CLR会把文件拷贝到一个临时目录下,然后在那运行web,而CLR只会拷贝托管文件,这就是为什
么我们明明把非托管的dll放在了bin下却依然提示不能加载模块了.
具体做法如下:
首先我们在服务器上随便找个地方新建一个目录,假如为C:\DLL
然后,在环境变量中,给Path变量添加这个目录
最后,把所有的非托管文件都拷贝到C:\DLL中.
或者更干脆的把DLL放到system32目录
对于可以自己部署的应用程序,这样未偿不是一个解决办法,然而,如果我们用的是虚拟空间,我们是没办法把注册PATH变量或者把我们自己的DLL拷到system32目录的。同时我们也不一定知道我们的Dll的物理路径。
DllImport里面只能用字符串常量,而不能够用Server.MapPath(@"~/Bin/Judge.dll")来确定物理路径。
ASP.NET中要使用DllImport的,必须在先“using System.Runtime.InteropServices;”
不过,我发现,调用这种"非托管Dll”相当的慢,可能是因为我的方法需要远程验证吧,但是实在是太慢了。
经过一翻研究,终于想到了一个完美的解决办法
首先我们用
[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(String path);
[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr lib, String funcName);
[DllImport("kernel32.dll")]
private extern static bool FreeLibrary(IntPtr lib);
分别取得了LoadLibrary和GetProcAddress函数的地址,再通过这两个函数来取得我们的DLL里面的函数。
我们可以先用Server.MapPath(@"~/Bin/Judge.dll")来取得我们的DLL的物理路径,然后再用LoadLibrary进行载入,最后用GetProcAddress取得要用的函数地址
以下自定义类的代码完成LoadLibrary的装载和函数调用:
上面是地址。
现在就不知道怎么搞,怎么写写在哪里,搞不清楚!
麻烦大家帮帮忙!
DllInvoke dll = new DllInvoke(Server.MapPath(@"~/Bin/Judge.dll"));
Compile compile = (Compile)dll.Invoke("Compile", typeof(Compile));
StringBuilder inf;
compile(@“gcc a.c -o a.exe“,inf);
2.把dll拷贝到bin目录下,直接在vs2005里面调试是不行的,因为调试网站是在vs自带的Web服务器里面运行的,利用的文件是...\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files这个目录下的临时文件来运行的,但这里没有DLL所以调试是达不到效果的。但是把dll文件放在windows/system32目录下,然后直接在vs2005里面调试是可以的。
3.如果给网站加个解决方案(*.sln),保持dll和这个sln文件在同一级目录下,在vs2005调试是可以的,但发布后是不行的。
综上所述,建议:调试时将dll文件放在windows/system32目录下,发布时将dll文件放在bin目录下即可。
我打印机是三星的T400,然后打印机有提供指令集,是封装在DLL中的。我现在用里面的一些方法,在WINFORM中可以直接把这个DLL拷到Debug的EXE同目录下,这样程序执行自动把这个DLL加载到内存里。
我现在是在网页上想调用这个DLL中的方法,理论上,是通过
[DllImport("bxllib.dll")]
将类加载到内存中,然后在使用
public static extern bool ConnectPrinter(string szPrinterName);
这样的形式,就可以使用了。。可是他提示找不到bxllib.dll,路径不对,然后我给了绝对路径,
[DllImport(@"E:\项目\lianxi\Bin\bxllib.dll")]
public static extern bool ConnectPrinter(string szPrinterName);
这样就OK啦。。
可是问题是,网站放在虚拟空间上,哪能给绝对路径呀,又不能给Server.MapPath("")这样的,因为DllImport()里面只能是字符串。。网上找了方法,可是不会用。
http://www.360doc.com/content/10/0602/14/957410_30860125.shtml
上面这个地址将的问题,就是我现在的问题,可是他给的这个是自己用例外一个语言写的DLL,自己可以改,我这个根本就不能像他那么改真不知道怎么解决。麻烦大家帮帮忙啦。。
SetDllDirectory 把你自己的目录添加到dll查找顺序中就成[DllImport("kernel32.dll", SetLastError=true)]
static extern bool SetDllDirectory(string lpPathName);
SetDllDirectory(mapath("~/xxx/"));不过我很怀疑能否运行,因为调用系统api和标准dll理论上是需要一点权限的
static extern bool SetDllDirectory(string lpPathName);
这个,你哪里来的这个方法呢?很郁闷呀!!!
{
string path = System.Web.HttpContext.Current.Server.MapPath("..\\Bin\\DLL\\EQ2008_Dll.dll");
library = IntPtr.Zero;
library = LoadLibrary(path); //加载DLL
if (library == IntPtr.Zero)
throw (new Exception("未载入有效的DLL模块, 请确认DLL文件: 是否有效!"));
hApi = GetProcAddress(library, "User_AddTime");//获得函数的指针
if (hApi == IntPtr.Zero)
throw (new Exception("无效的函数名: ")); } ~EQ_Sender() //卸载调用的DLL
{
FreeLibrary(library);
library = IntPtr.Zero;
hApi = IntPtr.Zero;
closeScreen(CardNum);
}
这样装载过之后就可以直接写
//添加时间区
[DllImport("EQ2008_Dll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int User_AddTime(int CardNum, ref User_DateTime myDataTime, int iProgramIndex);
哥就是这样处理的
在LoadDll() 时 总提示找不到DLL ,绝对路径相对路径都用过 ,不行,楼主的问题最后如何解决的?
[DllImport("kernel32.dll")]
public extern static int LoadLibraryEx(string lpLibFileName, int hFile, int dwFlags); //在调用自己的dll函数之前
DLLInvoke.LoadLibraryEx(
System.IO.Path.Combine(AppDomain.CurrentDomain.SetupInformation.PrivateBinPath, "/*我的dll名称*/"),
0,
8 //LOAD_WITH_ALTERED_SEARCH_PATH
);