我有一个非托管DLL,如果输入参数是一个很大的值,它可以运行很长时间,有时这是可取的但不总是.
我如何在c#中调用此函数以便在需要时可以中止它?
到目前为止,我已经尝试将调用放在一个单独的线程中,但是中断和中止似乎都没有停止进程,该进程在100%CPU运行直到dll完成.
是否可以终止正在运行的DLL代码?
假设我们有一个结构,它的数据由使用Marshal.PtrToStructure的非托管字节数组提供.
C#结构布局:
[StructLayout(LayoutKind.Sequential, Size = 128, CharSet = CharSet.Ansi, Pack = 1)]
public struct MNG_Y_Params
{
public byte Number;
public byte Version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] OliNumber;
public byte InterfaceType;
}
Run Code Online (Sandbox Code Playgroud)
字节数组表示未托管代码中的(ascii)字符串.
此结构是另一个结构的成员(具有一些其他成员):
public struct MyData
{
public int ID;
public StructType structType;
[XmlElement(ElementName="MNG_Y_Params")]
public MNG_Y_Params y_params;
[XmlElement(ElementName = "SimpleStruct2")]
public SimpleStruct2 ss2;
};
Run Code Online (Sandbox Code Playgroud)
所以我们也有这个支持代码
public class XMLIgnore
{
static public XmlSerializer customserialiser(MyData d)
{
XmlAttributes attrs = new XmlAttributes();
attrs.XmlIgnore = true;
XmlAttributeOverrides xmlOveride = new XmlAttributeOverrides(); …Run Code Online (Sandbox Code Playgroud) 我有一个非托管的dll,里面有一个"MyClass"类.现在有没有办法用C#代码创建这个类的实例?要调用它的构造函数?我试过了,但是visual studio报告了一个错误消息,指出这个内存区域已损坏或有什么东西.
提前致谢
我的C#代码使用托管C++包装器.要创建这个Wrapper类型的新对象,我需要将String转换为Sbyte*.一些StackOverflow.com帖子讨论了如何将String转换为byte [],以及将byte []转换为sbyte [],而不是String转换为sbyte*.
msdn.social.com提供有关如何将字节数组转换为字符串的建议:
> // convert String to Sbyte*
> string str = "The quick brown, fox jumped over the gentleman.";
>
> System.Text.ASCIIEncoding encoding = new
> System.Text.ASCIIEncoding();
>
> Byte[] bytes = encoding.GetBytes(str);
Run Code Online (Sandbox Code Playgroud)
但是,"bytes"不是sbyte*类型.我以下尝试将字节转换为sbyte*失败:
Run Code Online (Sandbox Code Playgroud)1. Convert.ToSbyte(bytes); 2. cast: (sbyte*) bytes;
请告诉我如何将C#字符串转换为sbyte*.
另外,请谈谈介绍sbyte*的任何副作用,我认为这是不安全的代码.
谢谢,凯文
我的解决方案中有以下三个项目:1.C#库2. C++/CLI托管代码3. C++非托管代码
我在我的C#项目中检查了"启用非托管代码调试",并在Debug/Win32中构建了两个C++项目.但是,我无法进入非托管代码 - 当我在调用任何非托管方法的F11时,它会显示一些随机/错误代码然后退出.
因为我的单元测试通过了,所以我知道我的非托管代码确实执行了.
我错过了什么?
最近我一直在尝试实现一些从InfoPath XSN文件(.CAB存档)中提取文件的功能.在广泛搜索互联网之后,似乎没有本地.NET API.所有当前的解决方案都围绕着大型库,即托管的C++,它包含了Cabinet.dll.
可悲的是,所有这些都违反了我的公司"没有第三方图书馆"的政策.
从2.0开始,.NET获得了一个名为UnmanagedFunctionPointer的属性,该属性允许使用__cdecl进行源级回调声明.在此之前,__ stdcall是镇上唯一的节目,除非你不介意捏造IL,这种做法在这里也是非法的.我立即知道这将允许为Cabinet.dll实现一个相当小的C#包装器,但我无法在任何地方找到一个示例.
有没有人知道使用本机代码执行此操作的方式比下面更清晰?
我当前的解决方案(执行非托管代码,但完全正常,在32/64位上测试):
[StructLayout(LayoutKind.Sequential)]
public class CabinetInfo //Cabinet API: "FDCABINETINFO"
{
public int cbCabinet;
public short cFolders;
public short cFiles;
public short setID;
public short iCabinet;
public int fReserve;
public int hasprev;
public int hasnext;
}
public class CabExtract : IDisposable
{
//If any of these classes end up with a different size to its C equivilent, we end up with crash and burn.
[StructLayout(LayoutKind.Sequential)]
private class CabError //Cabinet API: "ERF"
{
public int erfOper; …Run Code Online (Sandbox Code Playgroud) 我正在编写一个使用一些非托管代码的跨平台.NET库.在我的类的静态构造函数中,检测平台并从嵌入式资源中提取适当的非托管库并保存到临时目录,类似于另一个stackoverflow应答中给出的代码.
因此,当它不在PATH中时可以找到它,我在将它保存到临时文件后显式加载它.在Windows上,这可以LoadLibrary从kernel32.dll 正常工作.我正在尝试dlopen在Linux上做同样的事情,但是DllNotFoundException后来在加载P/Invoke方法时我得到了一个.
我已经验证库"libindexfile.so"已成功保存到临时目录并且调用dlopen成功.我钻研了单声道来源,试图弄清楚发生了什么,我想可能归结为是否随后的调用dlopen会重用以前加载的库.(当然假设我通过单声道源头的天真一举得出了正确的结论).
这是我正在尝试做的形状:
// actual function that we're going to p/invoke to
[DllImport("indexfile")]
private static extern IntPtr openIndex(string pathname);
const int RTLD_NOW = 2; // for dlopen's flags
const int RTLD_GLOBAL = 8;
// its okay to have imports for the wrong platforms here
// because nothing will complain until I try to use the
// function
[DllImport("libdl.so")]
static extern IntPtr dlopen(string filename, int …Run Code Online (Sandbox Code Playgroud) 我对iOS-Development和swift相对较新.但到目前为止,我总是能够通过对stackoverflow和一些文档和教程的一些研究来帮助自己.但是,有一个问题我找不到任何解决方案.
我想从用户地址簿中获取一些数据(例如单值属性kABPersonFirstNameProperty).因为.takeRetainedValue()如果此联系人在地址簿中没有firstName值,该函数会抛出错误,我需要确保该ABRecordCopyValue()函数确实返回一个值.我试图在一个闭包中检查这个:
let contactFirstName: String = {
if (ABRecordCopyValue(self.contactReference, kABPersonFirstNameProperty) != nil) {
return ABRecordCopyValue(self.contactReference, kABPersonFirstNameProperty).takeRetainedValue() as String
} else {
return ""
}
}()
Run Code Online (Sandbox Code Playgroud)
contactReference 是一个类型的变量 ABRecordRef!
当地址簿联系人提供firstName值时,一切正常.但是如果没有firstName,则应用程序会崩溃.takeRetainedValue().似乎if语句没有帮助,因为ABRecordCopyValue()虽然没有firstName,但函数的非托管返回值不是nil.
我希望我能够清楚地解决问题.如果有人能帮我解决一些脑波,那将是很棒的.
我有点生疏,实际上我的C++真的很生疏.从大学一年级开始就没有触及它,所以已经有一段时间了.
无论如何,我正在做与大多数人相反的事情.从C++调用C#代码.我在网上做了一些研究,似乎我需要创建一些托管C++来形成一个桥梁.使用__declspec(dllexport)然后从中创建一个dll并使用整个东西作为包装器.
但我的问题是 - 我真的很难找到例子.我找到了一些基本的东西,有人想将C#版本用于String.ToUpper(),但这是非常基本的,只是一个小代码片段.
任何人都有任何想法,我可以在哪里寻找更具体的东西?注意,我不想使用COM.目标是根本不触及C#代码.
包含托管代码和非托管代码混合的.NET程序集不能与其他程序集进行ILMerged.
如何验证给定的.NET程序集是包含纯托管代码,还是托管代码和非托管代码的混合?