我从我想在c#应用程序中使用的人那里得到了这个程序集.
标题看起来像这样:
int __declspec(dllimport) s2o(WCHAR* filename, char** out, int* len);
Run Code Online (Sandbox Code Playgroud)
我设法让它部分工作,使用:
[DllImport("s2o.dll", EntryPoint = "?skn2obj@@YAHPA_WPAPADPAH@Z", CallingConvention = CallingConvention.Cdecl)]
public static extern int s2o(
[MarshalAs(UnmanagedType.LPWStr)]
string filename,
ref char[] @out,
ref int len
);
Run Code Online (Sandbox Code Playgroud)
然后像这样调用它:
char[] result = null;
int length = 0;
s2o("filepath", ref result, ref length);
Run Code Online (Sandbox Code Playgroud)
它似乎部分起作用,因为'长度'实际上得到了一个值.不幸的是,'结果'保持为空.
我该怎么做才能让这个工作?
编辑:
好吧,我设法通过用IntPtr替换char []然后像Nick建议调用'Marshal.PtrToStringAnsi'来工作:
string result = Marshal.PtrToStringAnsi(ptr);
Run Code Online (Sandbox Code Playgroud)
但是,由于同一回答中的评论,我有点担心内存使用情况.装配中没有其他方法,所以我该如何清理?
目前正在使用Add-in Express开发Outlook加载项,我必须恢复一些纯MAPI函数来读取MAPI属性.
将此P/Invoke包装器添加到HrGetOneProp函数中:
[DllImport(@"MAPI32.DLL")]
static extern int HrGetOneProp(IntPtr pmp, uint ulPropTag, out IntPtr ppProp);
Run Code Online (Sandbox Code Playgroud)
我正在尝试将类型的Outlook附件对象IMAPIProp作为第一个参数传递给函数.
我目前失败的是如何将该对象"转换"为一个,IntPtr以便我可以将它作为函数的第一个参数传递给我.我试图使用,Marshal.StructureToPtr但显然这失败了一个例外,因为我没有传递结构,而只是一个非托管COM对象的引用.
所以我的问题是:
如何HrGetOneProp通过传递COM对象成功调用该方法?
我正在尝试使用C#代码中的CryptoAPI将SHA256时间戳添加到已签名的程序集中.这是我正在使用的代码:
Signer.TimestampSignedAssembly("MyAssembly.exe", "http://tsa.starfieldtech.com");
Run Code Online (Sandbox Code Playgroud)
签名者类:
public static class Signer
{
[StructLayoutAttribute(LayoutKind.Sequential)]
struct SIGNER_SUBJECT_INFO
{
public uint cbSize;
public IntPtr pdwIndex;
public uint dwSubjectChoice;
public SubjectChoiceUnion Union1;
[StructLayoutAttribute(LayoutKind.Explicit)]
internal struct SubjectChoiceUnion
{
[FieldOffsetAttribute(0)]
public IntPtr pSignerFileInfo;
[FieldOffsetAttribute(0)]
public IntPtr pSignerBlobInfo;
}
}
[StructLayoutAttribute(LayoutKind.Sequential)]
struct SIGNER_FILE_INFO
{
public uint cbSize;
public IntPtr pwszFileName;
public IntPtr hFile;
}
[DllImport("Mssign32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int SignerTimeStampEx2(
uint dwFlags, // DWORD
IntPtr pSubjectInfo, // SIGNER_SUBJECT_INFO
string pwszHttpTimeStamp, // LPCWSTR
uint dwAlgId, …Run Code Online (Sandbox Code Playgroud) 我提供了一个库,我知道它使用C++.我这样导入了DLL:
[DllImport("pst")] private static extern int pst_get_sensor(ref PSTSensor sensor);
PSTSensor是一个结构体,在C++示例中它被定义为:
struct PSTSensor
{
char name[80]; /**< Device name */
int id; /**< Device identifier (for other tracking interfaces */
float pose[16]; /**< Device pose estimate as row-major matrix */
double timestamp; /**< Time the data was recorded */
};
Run Code Online (Sandbox Code Playgroud)
问题是,除了Int和Double之外,它还使用Float,更重要的是数组.数组在C#和C++之间有所不同.在pst_get_sensor(ref sensor);运行代码时使用此结构调用整个开发环境时崩溃了.
我目前在C#中使用这样的结构:
struct PSTSensor{
public char[] name;
public int id;
public float[] pose;
public double timestamp;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,我如何创建一个C++理解的数组,并正确返回?这甚至可能吗?
非常感谢,Smiley
我一直试图使用p/invoke setupapi调用获取给定网络适配器的PnPDeviceId但没有成功.我不情愿地决定使用WMI,如下所示:
public static string GetPnpDeviceId(string mac)
{
ManagementObjectCollection mo = Management.GetCollection("Win32_NetworkAdapter", "PNPDeviceID", "MACAddress = '" + mac + "'");
return GetFirstValueString(mo, "PNPDeviceID");
}
public static ManagementObjectCollection GetCollection(string WMIClass, string WMISelect="*", string WMIWhere="")
{
string qry = "SELECT " + WMISelect + " FROM " + WMIClass + (WMIWhere == "" ? "" : " WHERE " + WMIWhere);
ObjectQuery oq = new System.Management.ObjectQuery(qry);
ManagementObjectSearcher query = new ManagementObjectSearcher(oq);
ManagementObjectCollection queryCollection = query.Get();
return queryCollection;
}
public static string GetFirstValueString(ManagementObjectCollection …Run Code Online (Sandbox Code Playgroud) WinAPI CreateProcess具有标志CREATE_SUSPENDED,因此可以在完成某些操作之前将进程附加到JobObject,然后为其主线程调用ResumeThread.我找到的唯一一个寻找解决方案的是11年前写的这篇文章!
http://khason.net/images/2008/12/image-32.png
var ID = 1234;
var FilePath = "C:\\file.dll";
IntPtr hMod = LoadLibraryEx(FilePath, IntPtr.Zero, 2); //LOAD_LIBRARY_AS_DATAFILE = 2
IntPtr hRes = FindResource(hMod, "#" + ID, "PNG");
byte[] Bytes = new byte[SizeofResource(hMod, hRes)];
Marshal.Copy(LoadResource(hMod, hRes), Bytes, 0, Bytes.Length);
FreeLibrary(hMod);
System.IO.File.WriteAllBytes("C:\\img.png", Bytes);
Run Code Online (Sandbox Code Playgroud)
上面的代码适用于PNG和其他自定义类型,但它不起作用BITMAP,我尝试了所有可能的组合:
FindResource(hMod, "#" + ID, "RT_BITMAP");
FindResource(hMod, "#" + ID, "BITMAP");
FindResource(hMod, "#" + ID, "Bitmap");
FindResource(hMod, "#" + ID, "BMP");
FindResource(hMod, ID, "Bitmap"); //also changed P/Invoke signature
FindResource(hMod, ID, "BITMAP"); //...
FindResource(hMod, ID, "BMP");
Run Code Online (Sandbox Code Playgroud)
有谁知道我在这里失踪了什么? …
我有一个下面的DLL源代码.
library Project1;
uses
System.SysUtils,
System.Classes;
type
IStringFunctions = interface
['{240B567B-E619-48E4-8CDA-F6A722F44A71}']
function GetMethodValueAsString():PAnsiChar; stdcall;
end;
TStringFunctions = class(TInterfacedObject, IStringFunctions)
public
function GetMethodValueAsString():PAnsiChar; stdcall;
end;
{$R *.res}
function TStringFunctions.GetMethodValueAsString():PAnsiChar; stdcall;
begin
Result := 'test';
end;
procedure GetImplementation(out instance:IStringFunctions); stdcall; export;
begin
instance := TStringFunctions.Create;
end;
exports GetImplementation;
begin
end.
Run Code Online (Sandbox Code Playgroud)
我想在C#中使用这样的
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
[ComVisible(true)]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("240B567B-E619-48E4-8CDA-F6A722F44A71")]
public interface IStringFunctions
{
[MethodImplAttribute(MethodImplOptions.PreserveSig)]
[return: MarshalAs(UnmanagedType.AnsiBStr)]
string GetMethodValueAsString();
}
class Program
{
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary", CallingConvention …Run Code Online (Sandbox Code Playgroud)