2016-04-16 13 views
-1

Ich versuche, einen Vulkan-Wrapper in C# erstellen, aber ich habe einige Probleme, wenn ich eine Funktion aufrufen. Ich schrieb die vulkan.h Header wie folgt:C# DllImport: AccessViolationException beim Aufruf eines vkCreateInstance

public static class Vk { 
    [StructLayout(LayoutKind.Sequential)] public class Instance { } 

    public enum Result { 
     ... 
    } 
    public enum StructureType { 
     ... 
    } 

    [StructLayout(LayoutKind.Sequential)] public class ApplicationInfo { 
     public StructureType sType; 
     public IntPtr pNext; 
     public string pApplicationName; 
     public uint applicationVersion; 
     public string pEngineName; 
     public uint engineVersion; 
     public uint apiVersion; 
    } 

    [StructLayout(LayoutKind.Sequential)] public class InstanceCreateInfo { 
     public StructureType sType; 
     public IntPtr pNext; 
     public uint flags_VkInstanceCreateFlags; 
     public ApplicationInfo pApplicationInfo; 
     public uint enabledLayerCount; 
     public string[] ppEnabledLayerNames; 
     public uint enabledExtensionCount; 
     public string[] ppEnabledExtensionNames; 
    } 

    [DllImport("vulkan-1.dll", EntryPoint = "vkCreateInstance")] 
    public extern static Result CreateInstance(
     InstanceCreateInfo pCreateInfo, 
     IntPtr AllocationCallbacks_pAllocator, 
     out IntPtr pInstance_Instance); 
} 

Die ursprüngliche Erklärung in C dieser Funktion

VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(
    const VkInstanceCreateInfo*     pCreateInfo, 
    const VkAllocationCallbacks*    pAllocator, 
    VkInstance*         pInstance); 

Nun ist, wenn ich meine Funktion aufrufen, ich bin wie dies zu tun:

Vk.InstanceCreateInfo instance_create_info = new Vk.InstanceCreateInfo(); 
... 

IntPtr hinstance; 
Vk.Result result = Vk.CreateInstance(instance_create_info, IntPtr.Zero, out hinstance); <-- error AccessViolationException 

Ich verstehe nicht, wo ist mein Problem, denn es scheint eine gültige Lösung zu sein: StackOverflow : AccessViolationException when calling vkEnumeratePhysicalDevices via pInvoke from c#.

Ich habe versucht, durch meine Initialisierung IntPtr hInstance mit

Marshal.AllocHGlobal(Marshal.SizeOf<Vk.Instance>()); 

Ich habe auch versucht zu meiner instance_create_info zu einem anderen IntPtr mit Marshal.StructureToPtr (...) "konvertieren"; und ich habe versucht instance_create_info und instance durch das Schlüsselwort ref übergeben. Offensichtlich hat nichts funktioniert.

Irgendeine Idee?


EDIT:

Die native Funktion wird wie folgt verwendet:

//Definition 
typedef struct VkApplicationInfo { 
    VkStructureType sType; 
    const void*  pNext; 
    const char*  pApplicationName; 
    uint32_t   applicationVersion; 
    const char*  pEngineName; 
    uint32_t   engineVersion; 
    uint32_t   apiVersion; 
} VkApplicationInfo;` 
typedef struct VkInstanceCreateInfo { 
    VkStructureType    sType; 
    const void*     pNext; 
    VkInstanceCreateFlags  flags; 
    const VkApplicationInfo* pApplicationInfo; 
    uint32_t     enabledLayerCount; 
    const char* const*   ppEnabledLayerNames; 
    uint32_t     enabledExtensionCount; 
    const char* const*   ppEnabledExtensionNames; 
} VkInstanceCreateInfo; 

#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; 
VK_DEFINE_HANDLE(VkInstance) 

//Code 
VkApplicationInfo application_info{}; 
    application_info.sType     = VK_STRUCTURE_TYPE_APPLICATION_INFO; 
    application_info.apiVersion    = VK_API_VERSION; 
    application_info.applicationVersion  = VK_MAKE_VERSION(1, 0, 0); 
    application_info.pApplicationName  = ""; 
    application_info.engineVersion   = VK_MAKE_VERSION(1, 0, 0); 
    application_info.pEngineName   = ""; 

VkInstanceCreateInfo instance_create_info{}; 
    instance_create_info.sType      = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; 
    instance_create_info.pApplicationInfo   = &application_info; 
    instance_create_info.enabledLayerCount   = 0 
    instance_create_info.ppEnabledLayerNames  = nullptr 
    instance_create_info.enabledExtensionCount  = 0 
    instance_create_info.ppEnabledExtensionNames = nullptr 

VkInstance _instance = nullptr; 
assert(!vkCreateInstance(&instance_create_info, nullptr, &_instance)); 
+0

Es gibt nicht genug Informationen hier zu beantworten. Wir würden beide Seiten der Schnittstelle in vollem Umfang und eine Spezifikation der Semantik benötigen. Oder ein Beispiel C-Code aufrufen. –

+0

@DavidHeffernan Ich habe einen Beispielcode hinzugefügt. Sag mir, wenn du etwas anderes brauchst. – Clematrics

+0

Ich weiß nicht, wie das C# FFI funktioniert, aber "out IntPtr pInstance_Instance" sieht falsch aus. Das Argument out von 'vkCreateInstance' nimmt einen Doppelzeiger auf eine undurchsichtige Struktur; eine Ganzzahl ist möglicherweise nicht groß genug für den Zeiger. –

Antwort

1

es scheint, dass Sie versuchen, etwas Ähnliches zu tun einen Wrapper für die C# gemacht. Kann für Sie nützlich sein. Gehe zu Source/SharpVulkan/Generated/Funktionen.

public static unsafe Instance CreateInstance(ref InstanceCreateInfo createInfo, AllocationCallbacks* allocator = null) 
    { 
     Instance instance; 
     fixed (InstanceCreateInfo* __createInfo__ = &createInfo) 
     { 
      vkCreateInstance(__createInfo__, allocator, &instance).CheckError(); 
     } 
     return instance; 
    } 

    [DllImport("vulkan-1.dll", CallingConvention = CallingConvention.StdCall)] 
    internal static extern unsafe Result vkCreateInstance(InstanceCreateInfo* createInfo, AllocationCallbacks* allocator, Instance* instance); 

    internal static unsafe void EnumerateInstanceExtensionProperties(byte* layerName, ref uint propertyCount, ExtensionProperties* properties) 
    { 
     fixed (uint* __propertyCount__ = &propertyCount) 
     { 
      vkEnumerateInstanceExtensionProperties(layerName, __propertyCount__, properties).CheckError(); 
     } 
    } 

Hoffe, dass es hilfreich ist :)

-1

entfernen out Schlüsselwort für drittes Argument oder deklariert es als struct entspricht.

+0

Erste Arg ist eine Klasse, so bestanden durch Ref, -1 –

+0

Ich habe alle Ihre Vorschläge versucht, aber nichts hat funktioniert ... – Clematrics

+0

@David Heffernan oh mein Gott! das war ein Fehler, vielen Dank. Ich habe den Beitrag bearbeitet. –

Verwandte Themen