我有一些代码来加载程序集并获取所有类型,实现某个接口,就像这样(假设asm是一个有效的加载程序集).
var results = from type in asm.GetTypes()
where typeof(IServiceJob).IsAssignableFrom(type)
select type;
Run Code Online (Sandbox Code Playgroud)
现在我陷入困境:我需要创建这些对象的实例并在对象上调用方法和属性.我需要将对已创建对象的引用存储在一个数组中以供以后使用.
我是P/如图所示调用Graphviz .当我写这篇博客文章时,代码运行得很好.现在,我把在一起的HttpModule呈现使用代码Graphviz的图形,但我得到了AccessViolationException在agmemread.
// Native signature
Agraph_t agmemread(char *);
// P/Invoke Signature
[DllImport(LIB_GRAPH)]
private static extern IntPtr agmemread(string data);
// Usage
IntPtr g = agmemread(data);
Run Code Online (Sandbox Code Playgroud)
就像我说的,这之前完美无缺.但现在,我无法让我的代码适用于任何事情.即使我基于相同代码的旧Graphviz应用程序也不再起作用.
我可能有什么改变会导致这种情况?我甚至没有下载新版本的Graphviz或任何东西,所以DLL都是一样的.
编辑:我尝试string改为StringBuilder,但产生了相同的结果.然后,我添加了一个MarshalAs属性:
static extern IntPtr agmemread([MarshalAs(UnmanagedType.LPWStr)] string data);
Run Code Online (Sandbox Code Playgroud)
有了它,我不再得到一个AccessViolationException,但Graphviz无法正确读取字符串并返回空指针.
实现这一目标的最佳方法是什么?我有一个在C#windows服务中生成的文件名列表.我需要最终将它们放入STL集中,并将其推送到文件映射.我假设实际上在C#中创建这个结构要么被禁止,要么太难以值得,但我可以使用一个本机dll返回指向它创建的集合的指针,然后我在文件映射中传递?这里的任何想法都会有所帮助!
我有以下c函数
opaque_struct* create() {}
void free(opaque_struct*) {}
Run Code Online (Sandbox Code Playgroud)
我想用PInvoke调用它:
[DllImport("test")]
public static extern IntPtr create ();
[DllImport("test")]
public static extern void free (IntPtr);
Run Code Online (Sandbox Code Playgroud)
我想这样可以正常工作,但我正在寻找一种方法,在托管代码中明确声明"free"只接受由"create"返回的IntPtr,并避免意外传递从其他函数接收的其他IntPtr.
就所有托管代码而言,指向的结构是不透明的.
即使我只是给它一个新名称,没有额外的属性,也无法扩展IntPtr.
有没有办法制作这种类型的IntPtr?
在C#我有这个:
[DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
public static extern IntPtr GetDesktopWindow();
Run Code Online (Sandbox Code Playgroud)
我试图转换为VB.NET因此:
<DllImport("user32.dll", EntryPoint:="GetDesktopWindow")>
Function GetDesktopWindow() As IntPtr
End Function
Run Code Online (Sandbox Code Playgroud)
但我得到一个错误......"Imports System.Runtime.InteropServices.DllImportAttribute不能应用于实例方法."
有人可以解释我需要做些什么来解决这个问题,甚至更好,告诉我为什么?
谢谢!
我正在使用具有以下不透明句柄的第三方C库:
typedef struct _VendorHandle *VendorHandle;
Run Code Online (Sandbox Code Playgroud)
以下是供应商的C示例,说明如何加载句柄:
VendorHandle handle;
int err;
err = vendorLoadFile(&handle, "something.bin");
Run Code Online (Sandbox Code Playgroud)
我试图使用以下声明在C#中使用PInvoke调用此方法:
[DllImport("VendorLib.dll")]
static extern int vendorLoadFile(IntPtr handle, string path);
Run Code Online (Sandbox Code Playgroud)
然后我添加了以下代码来使用声明:
IntPtr handle = new IntPtr();
int code = vendorLoadFile(handle, path);
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我收到以下错误:
尝试读取或写入受保护的内存.这通常表明其他内存已损坏.
我知道DLL很好,PInvoke正在工作,因为我正在执行他们的vendorVersion()方法所以它必须是别的我做错了.
我是使用Windows文件系统的新手,我已经坚持了几天这个问题.我正在用C#进行编码,我想要的是获得目录的确切"磁盘大小",就像在Windows 7上的目录的属性对话框中显示的那样.
现在我能得到一个粗略的数字,通过每个文件和目录中的每个子目录遍历,使用API GetCompressedFileSize在kernel32.dll压缩文件和FileInfo.Length圆形的簇大小正常文件的多个属性.
我发现有些文件共享集群(?)(磁盘大小不是集群大小的倍数)而其他文件分别占用集群,那么我无法在磁盘上获得确切的大小,是否将大小舍入为集群的倍数大小与否.
还有一些符号链接不占用磁盘空间,我找不到将它们与普通目录区分开来的方法.我得到的大小远远大于确切的大小,因为我无法避免计算这些链接的大小.
我想必须有一个API或东西来获取磁盘上的确切文件或目录大小.那是什么?或者有更简单/更快的方法吗?谢谢您的帮助!
我在VS2010中使用Robert Giesecke Unmanaged Exports 1.2.6,我的目标是将一系列结构从c#(.NET 3.5)传递给delphi(D7).我不得不承认,我对德尔福并不熟悉.
我已经阅读过这篇文章,但建议的答案对我不起作用:当func在delphi中调用时,CPU调试窗口打开,如果我继续应用程序退出,无异常且没有所需的结果.
这是我试过的代码:
C#平台x86
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using RGiesecke.DllExport;
namespace ArrayTest
{
public class Class1
{
public struct Sample
{
[MarshalAs(UnmanagedType.BStr)]
public string Name;
}
[DllExport]
public static int func(
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
Sample[] samples,
ref int len
)
{
// len holds the length of the array on input
// len is assigned the …Run Code Online (Sandbox Code Playgroud) 我正在尝试P /调用SetFileTime,但似乎无法正常工作。它总是为我返回5的错误代码(访问被拒绝),我不确定为什么。这是我正在使用的代码:
void Main()
{
var pointer = CreateFile(@"C:\Users\User\Desktop\New folder\New Text Document.txt", FileAccess.ReadWrite, FileShare.None, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero);
Console.WriteLine(pointer);
var now = DateTime.Now.ToFileTime();
long lpCreationTime = now;
long lpLastAccessTime = now;
long lpLastWriteTime = now;
if (!SetFileTime(pointer, ref lpCreationTime, ref lpLastAccessTime, ref lpLastWriteTime))
Console.WriteLine(GetLastError());
CloseHandle(pointer);
}
[DllImport("kernel32.dll")]
static extern UInt32 GetLastError();
[DllImport("kernel32.dll", SetLastError = true)]
static extern Boolean SetFileTime(IntPtr hFile, ref long lpCreationTime, ref long lpLastAccessTime, ref long lpLastWriteTime);
[DllImport("kernel32.dll", SetLastError = true)]
static extern Boolean CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", CharSet …Run Code Online (Sandbox Code Playgroud) 我有本机功能
void SetValue(char *FieldName, void *pValue);
Run Code Online (Sandbox Code Playgroud)
我想改变它来调用早期的set callback/delegate
有签名的
void SetValueDelegate(string fieldName, IntPtr value);
Run Code Online (Sandbox Code Playgroud)
我这样称为本地SetValue:
int IntValue = 0;
SetValue("MyField", &IntValue);
Run Code Online (Sandbox Code Playgroud)
现在我认为我可以将其强制转换为托管委托:
void SetValueDelegate(string fieldName, IntPtr value)
{
if (fieldName == "MyField")
{
int intValue = (int)value;
}
}
Run Code Online (Sandbox Code Playgroud)
这不起作用.如果施放到长,它的值是204790096.
应该怎么做?