可能重复:
预处理器指令... C#
我有一个使用DLLImport导入的外部c ++ dll.如果我的应用程序在x64中编译,我需要导入这个dll的x64版本,如果是x86版本,我需要x86 dll.
实现这一目标的最佳方法是什么?
理想情况下,我想要一些预处理器指令,但我知道这在c#中不起作用?
更多信息:DLL由一个设置为AnyCPU的项目导入.父项目是确定应用程序是否编译为x64或x86的项目.我们为不同的客户编译两个版本 - 我想在两个版本中共享子项目.
我使用结构传递给非托管DLL,因为 -
[StructLayout(LayoutKind.Sequential)]
public struct valTable
{
public byte type;
public byte map;
public byte spare1;
public byte spare2;
public int par;
public int min;
public byte[] name;
public valTable()
{
name = new byte[24];
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码将无法编译,因为VS 2005会抱怨"Structs不能包含显式无参数构造函数".为了将这个结构传递给我的DLL,我必须像这样传递一个struct数组valTable[] val = new valTable[281];
我想说的是,当我说new,构造函数被调用并且它创建了一个像我试图演示的字节数组,因为DLL正在寻找每个维度中大小为24的字节数组.
我怎么能做到这一点?
我有一个winform应用程序(.NET 2.0 C#).从这个应用程序,我想启动另一个进程(另一个winform应用程序)并将其停靠到我的窗口(或至少让它看起来像停靠).到目前为止,我只能找到有关对接控件的信息,而不是单独进程中的窗口.我的第一个想法是获取窗口的句柄并使用非托管系统调用来设置窗口的高度/宽度和位置到我的停靠区域.但在我开始之前,我想检查一下你们中是否有人做过类似的事情.我可以访问我想要停靠的应用程序的源代码,但如果可以避免它,我宁愿不做任何更改.我对父应用程序的完整编程控制.有什么建议?提前致谢!
我是C++ DLL导入主题的新人,可能是我的问题很容易但我在谷歌上找不到它.
我有一个非常简单的C++ win32 dll:
#include <iostream>
using namespace std;
extern "C"
{
__declspec(dllexport) void __stdcall DisplayHellowFromDLL()
{
cout<<"Hi"<<endl;
}
}
Run Code Online (Sandbox Code Playgroud)
当我从C#调用此方法时,我没有任何问题,这里是C#代码
namespace UnmanagedTester
{
class Program
{
[DllImport(@"C:\CGlobalDll")]
public static extern void DisplayHellowFromDLL();
static void Main(string[] args)
{
Console.WriteLine("This is C# program");
DisplayHellowFromDLL();
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如我所料,输出是:"这是C#程序""嗨".
现在,如果我将C函数的声明更改为:
__declspec(dllexport) void DisplayHellowFromDLL()
Run Code Online (Sandbox Code Playgroud)
没有__stdcall,我也没有任何问题,问题是:
我什么时候才真正需要__declspec(dllexport)TYPE __stdcall,何时我只能使用__declspec(dllexport)TYPE?
非常感谢.
我有一个现有的应用程序P/Invokes到一个DLL与应用程序本身驻留在同一目录中.
现在(由于佳能生产了最疯狂的API之一)我需要支持这个API的两个版本,并在运行时确定我应该使用哪个(旧的或新的).由于DLL具有相同的名称(第一个加载具有相同名称的其他DLL,因此只重命名第一个将无法帮助我)我必须将它们保存在不同的目录中.
因此我的问题是:我有什么选择来控制DllImport声明中给出的DLL使用的目录?
我想我可以尝试以下两个想法中的任何一个:
1)在执行第一个P/Invoke之前使用"SetDllDirectory"设置我想要的目录,然后重置它.
2)使用"LoadLibraryEx"手动加载所需的DLL,并希望这样做.
但是,有没有更多的".NET:ish方式"首先尝试?
更新:我意识到我可以在两个单独的.Net程序集中填充对DLL的所有访问权限,然后将它们中的每一个放在一个带有相应API文件的单独目录中.然后我可以动态加载正确的.Net程序集,并自动加载正确的DLL.有什么理由不行吗?
我能想到一个:我将如何调试这些东西?有可能告诉Visual Studio一个程序集(包含在我的解决方案中)应该放在一个子目录中并从那里进行调试吗?
我知道有一个名为Dll to lib的工具,但开发人员要求1000美元.我只需要转换一个库一次,所以不容易证明这个价格.
我尝试了IMPLIB32.EXE,但我只是得到空的.lib文件.我怎么能做到这一点?也许我可以写一个简单的转换应用程序?
Added1:
Dll通常是stdcall而不是cdecl,用旧的C语言编写,而不是C#或.NET或C++.我现在需要从C++应用程序中调用它们.一个例子是SQLite.dll或zlib.dll.我无法访问这些dll的.lib文件.
Added2:
我为VS2008重新编写了这段代码 http://floodyberry.wordpress.com/2008/09/08/generating-dll-wrappers/, 并在此处下载了可下载的示例Dll等:http: //www.transferbigfiles.com/Get .aspx?id = 7d86fa0b-6ddc-4f6f-8d31-2c20824aae9a 这反过来又创建了一个创建Dll的项目.当我尝试编译Dll时,我收到链接器错误:AddShow.dll:致命错误LNK1107:文件无效或损坏:无法在0x300读取此处描述:http://list.isis.vanderbilt.edu/pipermail/udm-users /2006-March/000664.html 不确定如何继续.到目前为止如此接近
接下来我们转到这个方法
http://www.coderetard.com/2009/01/21/generate-a-lib-from-a-dll-with-visual-studio/
运行dumpbin参数/ exports C:\ path\to\AddShow.dll绝对没有做过一些研究
http://msdn.microsoft.com/en-us/library/aa446532.aspx 似乎需要从common/ide文件夹中找到mspdb71.dll(现在是mspdb80.dll),dumpbin.exe现在运行时出错:
致命错误LNK1106:无效文件或磁盘已满:无法寻求0x6179A这些线程表明dumpbin.exe的版本可能是问题
我有Microsoft(R)COFF/PE Dumper版本9.00.30729.01
所以我尝试了Microsoft(R)COFF二进制文件转储器版本5.12.8078但没有成功.经过多次阅读后,我不再接近了
http://support.microsoft.com/kb/815645 http://support.microsoft.com/kb/839286 http://markmail.org/message/p5vwzyfyv3bs6z34 http://fixunix.com/programmer/94825-fatal -错误- lnk1106,无效的文件,磁盘full.html
当我运行ProcMon时,我看到第一次出现queryopen和sqlite3.dll,当svchost.exe尝试打开它时失败,错误路径未找到.路径是C:\ Program Files\Microsoft Visual Studio 9.0\VC\bin\SQLITE3.DLL并且是正确的.如果我把它放在C盘的根部,那么我得到NAME NOT FOUND错误:
C:\ Program Files\Microsoft Visual Studio 9.0\VC\bin\link.exe.Local
C:\ Program Files\Microsoft Visual Studio 9.0\VC\bin\dumpbin.exe.Local
从link.exe和dumpbin.exe分别.我使用XPSP3而不是Vista,这是我对sysinternals的限制.什么是这些.local文件?
(csrss.exe也无法找到一些清单文件.)
所以没有成功,只是更神秘
补充3:
我试图从其安装位置\ Program Files\Microsoft Visual Studio 8\VC\bin运行dumpbin.exe,但操作系统说它无法找到mspdb80.dll.我从\ Program Files\Microsoft Visual Studio 8\Common7\IDE复制了mspdb80.dll,试图让dumpbin.exe运行.
现在我收到错误:"c1902程序数据库管理器不匹配,请检查您的安装"
如果我从\ Program Files\Microsoft Visual Studio …
我创建了一个包含类"myCppClass"的C++ Dll项目,并尝试使用以下代码将其导出:如下所述:http://msdn.microsoft.com/en-us/library/a90k134d( v = vs. 80)的.aspx
class __declspec(dllexport) CExampleExport : //public CObject
{ ... class definition ... };
Run Code Online (Sandbox Code Playgroud)
我省略了"public CObject",因为它需要afx.h并暗示它是一个MFC Dll.我不确定这是否是好事但它与DLL项目默认设置不同.
从上面链接的文档中我可以相信所有"公共函数和成员变量"都可以导入.我如何在C#中实现这一目标?可以简单地实例化该类吗?
编辑:我刚刚意识到帖子的标题可能会产生误导.重点应放在C#的DllImporting上,并确保我在C++中正确地遵循了文档
我有一个C#dll.代码如下:
public class Calculate
{
public static int GetResult(int arg1, int arg2)
{
return arg1 + arg2;
}
public static string GetResult(string arg1, string arg2)
{
return arg1 + " " + arg2;
}
public static float GetResult(float arg1, float arg2)
{
return arg1 + arg2;
}
public Calculate()
{
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我打算C++通过这种方式调用这个dll .
[DllImport("CalculationC.dll",EntryPoint="Calculate", CallingConvention=CallingConvention::ThisCall)]
extern void Calculate();
[DllImport("CalculationC.dll",EntryPoint="GetResult", CallingConvention=CallingConvention::ThisCall)]
extern int GetResult(int arg1, int arg2);
Run Code Online (Sandbox Code Playgroud)
这是函数,其中称为GetResult
private: System::Void CalculateResult(int arg1, int arg2)
{
int …Run Code Online (Sandbox Code Playgroud) 我有一个带有导出函数的C++ DLL:
extern "C" __declspec(dllexport) double* fft(double* dataReal, double* dataImag)
{
[...]
}
Run Code Online (Sandbox Code Playgroud)
该函数计算两个双数组(实数和虚数)的FFT,返回单个双数组,实数为虚数组件交错:{Re,Im,Re,Im,...}
我不知道如何在C#中调用此函数.我在做的是:
[DllImport("fft.dll")]
static extern double[] fft(double[] dataReal, double[] dataImag);
Run Code Online (Sandbox Code Playgroud)
当我像这样测试它:
double[] foo = fft(new double[] { 1, 2, 3, 4 }, new double[] { 0, 0, 0, 0 });
Run Code Online (Sandbox Code Playgroud)
我收到MarshalDirectiveException异常:
无法封送"返回值":无效的托管/非托管类型组合.
我假设这是因为C++ double*与C#不完全相同double[],但我不确定如何解决它.有任何想法吗?
编辑:我已经更改了签名,以便我现在传递一些额外的信息:
extern "C" __declspec(dllexport) void fft(double* dataReal, double* dataImag, int length, double* output);
Run Code Online (Sandbox Code Playgroud)
我们总是知道长度output是2倍length
和
[DllImport("fft.dll")]
static extern void fft(double[] dataReal, double[] dataImag, int length, out double[] …Run Code Online (Sandbox Code Playgroud) 我试图Windows Phone 8在Visual Studio Express 2012中向框架添加C++ DLL .
我试过以下方法
通过PInvoke导入和调用
[DllImport("WP8DLL.dll",CallingConvention = CallingConvention.Cdecl)]
public static extern int functionReturningInteger();
结果:这种方式虽然没有编译错误,但是当我尝试访问它抛出的DLL的方法时System.NotSupportedException.
在项目属性中添加引用
结果:我收到消息"无法将对更高版本或不兼容程序集的引用添加到项目中 "