2016-04-16 11 views
-1

C#でVulkanラッパーを作成しようとしていますが、関数を呼び出すときにいくつか問題があります。次のように私はvulkan.hヘッダを書き直し:C#DllImport:vkCreateInstanceを呼び出すときのAccessViolationException

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); 
} 

私は私の関数を呼び出すとき、この関数のCの元の宣言は今、私はこのような

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

やってるさ:

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

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

有効な解決策であると思われるため、私はどこに問題があるのか​​分かりません:StackOverflow : AccessViolationException when calling vkEnumeratePhysicalDevices via pInvoke from c#

私はまたMarshal.StructureToPtr(...)で、別ののIntPtrに私のinstance_create_infoを "変換" することを試みた

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

と私ののIntPtr HINSTANCEを初期化することを試みました。instance_create_infoをrefキーワードで渡そうとしました。明らかに、何も働かなかった。


EDIT次のよう

ネイティブ関数が使用される:

//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

答えるために、ここでの十分な情報はありません。インタフェースの両面とセマンティクスの仕様が必要です。または、Cのコード例を示します。 –

+0

@DavidHeffernanサンプルコードを追加しました。あなたに何か必要があるかどうか教えてください。 – Clematrics

+0

C#FFIの仕組みはわかりませんが、 'Out IntPtr pInstance_Instance'は間違っています。 'vkCreateInstance'のout引数は、不透明な構造体へのダブルポインタをとります。整数はポインタのために十分に大きくないかもしれません。 –

答えて

1

同様のことをしようとしているようだ。this guyはC#のラッパーを作った。あなたに役立つことができます。 Source/SharpVulkan/Generated/Functionsに移動します。

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(); 
     } 
    } 

は、それが参考になっている願っています:)

-1

第三引数のoutキーワードを削除するか、または構造体を対応として宣言。

+0

最初の引数はクラスなのでrefで渡されます-1 –

+0

私はあなたの提案をすべて試みましたが、何も働かなかった... – Clematrics

+0

@David Heffernan oh my god!それは間違いだった、ありがとう。私はその記事を編集した。 –

関連する問題