我有非托管代码:
...
typedef struct foo
{
int a;
bool b
int c;
} FOO,*LPFOO;
....
__declspec(dllexport) FOO __stdcall GetFoo()
{
FOO f;
<some work>
return f;
}
....
Run Code Online (Sandbox Code Playgroud)
我已经为GetFoo函数声明了C#原型:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct Foo
{
public int a;
public bool b
public int c;
};
[DllImport("foo.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
[return:MarshalAs( UnmanagedType.Struct)]
private static extern Foo GetFoo();
Run Code Online (Sandbox Code Playgroud)
但是当我从C#代码调用GetFoo时,我总是有MarshalDirectiveException- Method的类型签名不兼容PInvoke.我该如何申报C#原型?
我是第一次使用Managed C++ ...我使用Winform创建了一个表单,它有一个按钮来浏览目录中的文件以及用户选择的路径,该路径应该在文本框中可见.
我想知道如何在托管C++中创建文件浏览器对话框.
如果需要,附加表单的图像.

我有一个c ++/cli类,我想在其中维护托管字符串和本机指针之间的映射.
使用std :: map给编译器警告C4368(不能将'member'定义为托管'type'的成员:不支持混合类型).
使用Dictionary给出C3225:'TValue'的泛型类型参数不能是'native pointer',它必须是值类型或引用类型的句柄
我怎样才能实现这种映射?
我有一个.dll内置的C++/CLI和.NET.因此,它的目标是.NET应用程序.API是一组使用托管类型的包装器,因此它是.NET本机的.我导入了.dll并添加了一个函数:
[DllImport(@"maplib.dll")]
public static extern bool initialize(string a);
Run Code Online (Sandbox Code Playgroud)
当我在我的C#代码中调用此函数时,它工作正常,但如果我想添加另一个函数,如...
[DllImport(@"maplib.dll")]
public static extern bool initialize(string a);
public static extern bool runfile(string a, string b);
Run Code Online (Sandbox Code Playgroud)
我运行程序时遇到此错误.它与第二个功能有关:
"无法从程序集'myapp,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'加载类型'myapp.main',因为方法'runfile'没有实现(没有RVA)."
为什么会出现此错误,如何解决?
我已经为我的程序添加了一个类并进行了测试.我真的很惊讶有任何真正的错误.这是代码:
#pragma once
#include "Iingredient.h"
#include <string>
#include <vector>
using namespace std;
ref class Recipe{
private:
string partsName;
vector<Iingredient> ing;
public:
Recipe(){}
};
Run Code Online (Sandbox Code Playgroud)
以下是错误:
错误23错误C4368:无法将'partsName'定义为托管'Recipe'的成员:不支持混合类型c:\ users\user\documents\visual studio 2010\projects\smestras2_l1\Recipe.h 10 1 file2_L1
错误24错误C4368:无法将'ing'定义为托管'Recipe'的成员:不支持混合类型c:\ users\user\documents\visual studio 2010\projects\smestras2_l1\Recipe.h 11 1 file2_L1
我google了一下,发现它有关托管和非托管代码.如何解决这个问题?它是否与manged和非托管代码相关?如果是这样的话?
我继承了一个由许多C#,C++/CLI和本机C++项目组成的应用程序.
该应用程序作为MFC应用程序启动,但在启动期间加载CLR(通过我不确定我完全理解的过程†).
我发现我可以在本机C++代码中放置断点,并且这些断点可以按预期工作.但是,托管代码中的断点不起作用.
在C#我得到:
"断点当前不会被命中.此文档没有加载任何符号".
在C++/CLI中我得到:
"断点当前不会被命中.没有可执行代码与此行相关联.可能的原因包括:预处理程序指令或编译器/链接器优化".
我甚至可以在同一个C++文件中设置两个断点,并且只有一个工作,例如
#pragma unmanaged
int CMyClass::UnmanagedFunc()
{
// Breakpoint here works
return 1
}
#pragma managed
int CMyClass::ManagedFunc()
{
// Breakpoint here DOES NOT WORK!!
return 2
}
Run Code Online (Sandbox Code Playgroud)
"启用非托管代码调试"(在托管库项目中)的项目设置对这些断点没有影响.有一些设置或配置或东西,我不这样做,让我中断,并通过代码库的管理部分步骤?
†:该进程加载mscoree.dll,并涉及复杂的程序,包括CLRCreateInstance,ICLRMetaHost,ICLRRuntimeHost,GetRuntime(..),Start()和ExecuteInDefaultAppDomain(..).
我将字符串从非托管代码传递给托管有问题.在我的非托管类(unmanagedClass.cpp)中,我有一个指向托管代码函数的指针:
TESTCALLBACK_FUNCTION testCbFunc;
Run Code Online (Sandbox Code Playgroud)
TESTCALLBACK_FUNCTION接受一个字符串并且不返回任何内容:
typedef void (*TESTCALLBACK_FUNCTION )(char* msg);
Run Code Online (Sandbox Code Playgroud)
非托管类继承自ITest接口,该接口只有一个方法:
STDMETHOD(put_TestCallBack) (THIS_
LPVOID FnAddress
) PURE;
Run Code Online (Sandbox Code Playgroud)
在managedClass.cs中,我编写了这段代码:
public class ManagedClass
{
ITest unmanaged = new unmanagedClass();
public delegate void TestDelegate(string info);
ManagedClass()
{
unmanaged.put_TestCallBack(new TestDelegate(this.Test));
}
void Test(string info)
{
MessageBox.Show(info);
}
}
[ComImport, Guid("<my guid here>")]
public class unmanagedClass
{
}
[ComImport, System.Security.SuppressUnmanagedCodeSecurity,
Guid("<my guid here>"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ITest
{
[PreserveSig]
int put_TestCallBack([MarshalAs(UnmanagedType.FunctionPtr), In] Capture.TestDelegate func);
Run Code Online (Sandbox Code Playgroud)
}
要从非托管代码调用Test func,我使用它
(*testCbFunc)("Func Uragan33::Execute has been started!");
Run Code Online (Sandbox Code Playgroud)
但是当调用来自managedClass.cs的Test方法时,我总是收到空 …
我可以在非托管Delphi EXE中使用托管C#DLL吗?或者唯一的方法是拥有托管DLL和EXE或非托管DLL和EXE?
鉴于最新版本的C#7中新的ref locals和ref return功能,这个问题是新近相关的:
随着C#中托管变量或"内部" - 指针变量的突出和广泛使用,有时您可能需要为这样的指针恢复相应的包含 Pinnable GC对象.例如,如果要传递一个指向类型数组元素的托管指针T,则可能需要数组引用T[]本身才能调用(例如)Array.Copy(...).
所以,从托管代码,是否有任何合理合法以回收含GC对象句柄方式,给出以下两种流行内部的/管理的指针(
ref,out,in)使用:
- 指向GC对象实例中(
struct或class)字段的内部指针;- 管理指向Array 的(
struct或class)元素T的指针T[].
在.NET内部,GC似乎使用以下函数:/ coreclr/master/src/gc/gc.cpp
#ifdef INTERIOR_POINTERS
// will find all heap objects (large and small)
uint8_t* gc_heap::find_object (uint8_t* interior, uint8_t* low)
{
....
Run Code Online (Sandbox Code Playgroud)
此代码遍历已知的GC堆,检查指定的内部指针是否落在已知GC对象分配的范围内.显然,这种方法不容易从最终用户托管代码中访问,而且据我所知,如果没有GC正在进行中,则可能甚至不相关.
我还查看了新的Span<T>和System.Memory库,但是找不到一系列可以恢复(例如)数组句柄的操作,如果你没有从第一个位置提供它(那时包含的句柄在那些中被squirleled)各种结构).如果_pinnable是可选的(例如Span<T> …