错误的 DLL 调用约定
Wrong DLL calling convention
我正在尝试从 VB6 中调用 C++ COM DLL。
C++代码为:
STDMETHODIMP CSonic::sonicChangeShortSpeed(
SHORT* samples,
LONG *numSamples,
FLOAT speed,
FLOAT pitch,
FLOAT rate,
FLOAT volume,
LONG useChordPitch,
LONG sampleRate,
LONG numChannels
)
我在 VB6 中这样调用它:
Private Declare Function sonicChangeShortSpeed Lib "SonicLIB.dll" Alias "#1" (
ByRef samples As Integer,
ByRef numSamples As Long,
ByVal speed As Double,
ByVal pitch As Double,
ByVal rate As Double,
ByVal volume As Double,
ByVal useChordPitch As Long,
ByVal sampleRate As Long,
ByVal numChannels As Long)
As Long
在我的代码中,我使用:
Dim nIntegers() As Integer
ReDim nIntegers(2047)
Dim lSamples As Long
Dim dblSpeed As Double
Dim dblPitch As Double
Dim dblRate As Double
Dim dblVol As Double
Dim lUseChordPitch As Long
Dim lSampleRate As Long
Dim lNumChannels As Long
lSamples = 2048
dblSpeed = 0.5
dblPitch = 0
dblRate = 1
dblVol = 1
lUseChordPitch = 1
lSampleRate = 48000
lNumChannels = 1
Dim lRet As Long
lRet = sonicChangeShortSpeed(nIntegers(0), lSamples, dblSpeed, dblPitch, dblRate, dblVol, lUseChordPitch, lSampleRate, lNumChannels)
最后一行产生 "Wrong calling convention" 错误。
有人看出我的错误吗?
谢谢!
如果这是一个 COM DLL,您需要将它作为引用添加到您的 VB6 项目中,然后您就可以访问该 DLL 中包含的 classes 和其他 COM 定义。
或者,您可以只注册 DLL 而无需将其添加为引用,然后将 'late binding' 与 CreateObject() 调用一起使用。
但如果您不确定它是否是一个COM DLL,您可以通过以下方式检查:
- 尝试像使用regsvr32.exe一样在命令上注册它(可能需要管理员权限)。如果报告成功,则表示它是一个成功注册的 COM DLL。
- 拖放到Visual Studio自带的Oleview程序中。如果 DLL 是 COM,它通常会有一个 Oleview 将显示的类型库。如果不是 COM,这将产生错误。
如果它不是 COM DLL,那么我认为您的方法不一定有效。您正试图调用一个 class 方法,就好像它是一个普通的 'C' 样式函数一样。也许这适用于静态 C++ 方法——但这里似乎并非如此。
DLL 的传统 import/export table 对 classes 一无所知。您可能需要围绕 class 对象编写一个 C++ 包装函数,然后可以将其导出并在 VB6 中使用。包装器必须处理对象的创建、销毁等。
我正在尝试从 VB6 中调用 C++ COM DLL。
C++代码为:
STDMETHODIMP CSonic::sonicChangeShortSpeed(
SHORT* samples,
LONG *numSamples,
FLOAT speed,
FLOAT pitch,
FLOAT rate,
FLOAT volume,
LONG useChordPitch,
LONG sampleRate,
LONG numChannels
)
我在 VB6 中这样调用它:
Private Declare Function sonicChangeShortSpeed Lib "SonicLIB.dll" Alias "#1" (
ByRef samples As Integer,
ByRef numSamples As Long,
ByVal speed As Double,
ByVal pitch As Double,
ByVal rate As Double,
ByVal volume As Double,
ByVal useChordPitch As Long,
ByVal sampleRate As Long,
ByVal numChannels As Long)
As Long
在我的代码中,我使用:
Dim nIntegers() As Integer
ReDim nIntegers(2047)
Dim lSamples As Long
Dim dblSpeed As Double
Dim dblPitch As Double
Dim dblRate As Double
Dim dblVol As Double
Dim lUseChordPitch As Long
Dim lSampleRate As Long
Dim lNumChannels As Long
lSamples = 2048
dblSpeed = 0.5
dblPitch = 0
dblRate = 1
dblVol = 1
lUseChordPitch = 1
lSampleRate = 48000
lNumChannels = 1
Dim lRet As Long
lRet = sonicChangeShortSpeed(nIntegers(0), lSamples, dblSpeed, dblPitch, dblRate, dblVol, lUseChordPitch, lSampleRate, lNumChannels)
最后一行产生 "Wrong calling convention" 错误。
有人看出我的错误吗?
谢谢!
如果这是一个 COM DLL,您需要将它作为引用添加到您的 VB6 项目中,然后您就可以访问该 DLL 中包含的 classes 和其他 COM 定义。
或者,您可以只注册 DLL 而无需将其添加为引用,然后将 'late binding' 与 CreateObject() 调用一起使用。
但如果您不确定它是否是一个COM DLL,您可以通过以下方式检查:
- 尝试像使用regsvr32.exe一样在命令上注册它(可能需要管理员权限)。如果报告成功,则表示它是一个成功注册的 COM DLL。
- 拖放到Visual Studio自带的Oleview程序中。如果 DLL 是 COM,它通常会有一个 Oleview 将显示的类型库。如果不是 COM,这将产生错误。
如果它不是 COM DLL,那么我认为您的方法不一定有效。您正试图调用一个 class 方法,就好像它是一个普通的 'C' 样式函数一样。也许这适用于静态 C++ 方法——但这里似乎并非如此。
DLL 的传统 import/export table 对 classes 一无所知。您可能需要围绕 class 对象编写一个 C++ 包装函数,然后可以将其导出并在 VB6 中使用。包装器必须处理对象的创建、销毁等。