从Excel VBA使用C ++ DLL时“错误的DLL调用约定” - 如何解决?

问题描述 投票:1回答:2

我需要创建一个C ++ DLL,它有一个函数返回一个要在Excel(2010)VBA代码中使用的字符串。

我已经阅读了以下帖子:Using C++ DLL in Excel VBA - 以及Microsoft关于C ++ DLL创建和VBA使用的教程(Walkthrough: Create and use your own Dynamic Link Library (C++)Access DLLs in Excel)并遵循该过程。

这是代码:

C ++ DLL(摘自Microsoft网页):

// MathLibrary.h - Contains declarations of math functions
#pragma once

#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif

// The Fibonacci recurrence relation describes a sequence F
// where F(n) is { n = 0, a
//               { n = 1, b
//               { n > 1, F(n-2) + F(n-1)
// for some initial integral values a and b.
// If the sequence is initialized F(0) = 1, F(1) = 1,
// then this relation produces the well-known Fibonacci
// sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

// Initialize a Fibonacci relation sequence
// such that F(0) = a, F(1) = b.
// This function must be called before any other function.
extern "C" MATHLIBRARY_API void fibonacci_init(
    const unsigned int a, const unsigned int b);

// Produce the next value in the sequence.
// Returns true on success and updates current value and index;
// false on overflow, leaves current value and index unchanged.
extern "C" MATHLIBRARY_API bool fibonacci_next();

// Get the current value in the sequence.
extern "C" MATHLIBRARY_API unsigned int fibonacci_current();

// Get the position of the current value in the sequence.
extern "C" MATHLIBRARY_API unsigned fibonacci_index();

VBA代码(我的,遵循Microsoft文档):

Public Declare Sub fibonacci_init Lib "C:\development\MathLibrary\Release\MathLibrary.dll" (ByVal a As Integer, ByVal a As Integer)
Public Declare Function fibonacci_next Lib "C:\development\MathLibrary\Release\MathLibrary.dll" () As Boolean
Public Declare Function fibonacci_current Lib "C:\development\MathLibrary\Release\MathLibrary.dll" () As Integer

Public Function run_dll()
    Dim b As Integer

    Call fibonacci_init(1, 1)
    b = fibonacci_current()
End Function

当我在VBA中运行run_dll函数时,我得到一个例外:Call fibonacci_init(1,1)行上的“错误的DLL调用约定”。

这有什么不对?我已经将C ++函数声明为extern "C"所以我假设调用约定是固定的...

UPDATE

更多我尝试过的事情......

  1. 我根据评论/答案的提示从头开始创建了一个新的dll:

Trial.cpp:

const char* str = "abcdefg";

extern "C" __declspec(dllexport) int size()
{
    return strlen(str);
}

extern "C" __declspec(dllexport) bool test(char* pReturn)
{
    int nSize = strlen(str);
    lstrcpynA(pReturn, str, nSize);

    return true;
}

使用以下VBA:

Public Declare Function size Lib "C:\development\MathLibrary\Release\Trial.dll" () As Long
Public Declare Function test Lib "C:\development\MathLibrary\Release\Trial.dll" (ByVal p As Long) As Boolean

(1) Public Function run_dll()
(2)    Dim bb As Boolean
(3)    Dim sz As Integer
(4)    Dim s As String        
(5)    sz = size()       
(6)    s = Space(sz)        
(7)    bb = test(StrPtr(s))
(8) End Function

第5行工作正常 - sz收到7.但第7行给出“错误的DLL调用约定”。

  1. 尝试使用WINAPI声明C ++函数,就像我在阅读的帖子中提到的那样,给出:Can't find DLL entry point size in C:\development\MathLibrary\Release\Trial.dll
  2. test VBA声明更改为

Public Declare Function test Lib "C:\development\MathLibrary\Release\Trial.dll" (ByRef p As String) As Boolean

并调用(line7)作为bb = test(s) - 导致Excel崩溃

  1. test VBA声明更改为

Public Declare Function test Lib "C:\development\MathLibrary\Release\Trial.dll" (ByRef p As Long) As Boolean

并调用(line7)作为bb = test(StrPtr(s)) - 给出:“错误的DLL调用约定”

似乎什么都没有用。有人有这样的设置的工作示例吗?

c++ excel excel-vba dll
2个回答
1
投票

相当于C ++ Integer是一个VBA长。

VBA中的Integer是2字节数据类型,VBA中的Long是4字节数据类型。由于传递的字节数与预期的字节数不匹配,因此您将获得错误的DLL调用约定

请注意,VBA不支持无符号类型,因此您的输出将被解释为带符号的4字节整数(长整数)。


0
投票

您需要将其作为COM库。这些可以在Windows注册表中注册后导入VBA代码。

© www.soinside.com 2019 - 2024. All rights reserved.