QA@IT
«回答へ戻る

回答を投稿

stdcall と cdecl の続きです。

.NETで実行する

__stdcallなしの状態で、VB.NETで以下のコードを実行してみます。

Module1.vb

    Sub Main()
        Call (New Class1()).DoSomething()
    End Sub

Class1.vb

Public Class Class1
    Private Declare Function qait_sample Lib "felicalib.dll" (ByVal a As Integer, ByVal b As Integer) As Integer

    Sub DoSomething()
        Console.WriteLine(qait_sample(8, 2))
        Console.ReadKey()
    End Sub
End Class

LongがIntegerに直ってますが同じです。
この場合は実行できてしまいますね(ここの理由はちょっとわからないです、.NETだと自動で判別してくれるかもしれません)。

VB.NETでは別の呼び出し構文があり これを使うと CDECLであることを明示することができます。

Class1.vb

Imports System.Runtime.InteropServices

Public Class Class1
    <DllImport("felicalib.dll", CallingConvention:=CallingConvention.Cdecl)> _
    Private Shared Function qait_sample(ByVal a As Integer, ByVal b As Integer) As Integer
    End Function

    Sub DoSomething()
        Console.WriteLine(qait_sample(8, 2))
        Console.ReadKey()
    End Sub
End Class

長くなりましたが、気になるところです。
作者のサンプルでも、DllImportでCallingConvertionを指定していません。
現在でも指定せずに動いているかもしれませんが、指定したほうがいいんではないかと思います。

実際にはテストしてもらって決定してくれればいいと思いますが参考までに。

http://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.callingconvention(v=vs.110).aspx

Cdecl 呼び出し規約を適用する例を次に示します。呼び出し元によってスタックはクリーンアップされるため、これは必ず使用する必要があります。

stdcall と cdecl の続きです。

## .NETで実行する

__stdcallなしの状態で、VB.NETで以下のコードを実行してみます。

Module1.vb
```
    Sub Main()
        Call (New Class1()).DoSomething()
    End Sub
```

Class1.vb
```
Public Class Class1
    Private Declare Function qait_sample Lib "felicalib.dll" (ByVal a As Integer, ByVal b As Integer) As Integer

    Sub DoSomething()
        Console.WriteLine(qait_sample(8, 2))
        Console.ReadKey()
    End Sub
End Class
```

LongがIntegerに直ってますが同じです。
この場合は実行できてしまいますね(ここの理由はちょっとわからないです、.NETだと自動で判別してくれるかもしれません)。

VB.NETでは別の呼び出し構文があり これを使うと CDECLであることを明示することができます。

Class1.vb
```
Imports System.Runtime.InteropServices

Public Class Class1
    <DllImport("felicalib.dll", CallingConvention:=CallingConvention.Cdecl)> _
    Private Shared Function qait_sample(ByVal a As Integer, ByVal b As Integer) As Integer
    End Function

    Sub DoSomething()
        Console.WriteLine(qait_sample(8, 2))
        Console.ReadKey()
    End Sub
End Class
```

長くなりましたが、気になるところです。
作者のサンプルでも、DllImportでCallingConvertionを指定していません。
現在でも指定せずに動いているかもしれませんが、指定したほうがいいんではないかと思います。

実際にはテストしてもらって決定してくれればいいと思いますが参考までに。

http://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.callingconvention(v=vs.110).aspx

> Cdecl 呼び出し規約を適用する例を次に示します。呼び出し元によってスタックはクリーンアップされるため、これは必ず使用する必要があります。