导出函数,通过DLL强制转换为指针

时间:2015-11-12 08:23:55

标签: c++ c function-pointers dllexport

这是对早期问题的阐述:How to reset state machines when unit testing C
还有一个类似的问题,但我的答案与我的问题不符,我想提出一些例子:Exporting a function pointer from dll

我有两组代码,我希望它们应该做同样但后者崩溃。 使用mingw32和Win7。

要导出的功能。这被认为是遗产和不可改变的 addxy.c

    int addXY(int x, int y)
    {
      return x + y;
    }    

addxy.h

    int addXY(int x, int y);

工作示例

的main.c

    #include <stdio.h>
    #include "addxy.h"

    typedef int (__cdecl *addXYWrap_t)(int a, int b);

    addXYWrap_t addXYWrap = (addXYWrap_t)addXY;

    void main()
    {
      printf("result: %d", addXYWrap(3, 4));
    }

屈服

result: 7

崩溃的例子

addxydll.c

    #include <stdio.h>
    #include "addxy.h"

    typedef int (__cdecl *addXYWrap_t)(int a, int b);

    __declspec(dllexport) addXYWrap_t addXYWrap = (addXYWrap_t)addXY;

的main.c

    #include <windows.h>
    #include <stdio.h>

    typedef int (__cdecl *func)(int a, int b);

    void main()
    {
      HINSTANCE loadedDLL = LoadLibrary("addxy.dll");

      if(!loadedDLL) {
        printf("DLL not loaded");
        return;
      } else {
        printf("DLL loaded\n");
      }

      func addition = (func)GetProcAddress(loadedDLL, "addXYWrap");

      if(!addition) {
        printf("Func not loaded");
        return;
      } else {
        printf("Func loaded\n");
      }

      printf("result: %d", addition(3, 4));
    }

屈服

DLL loaded
Func loaded
在它崩溃之前

崩溃没有提供关于为什么或什么的信息 这是语法错误还是概念错误?

3 个答案:

答案 0 :(得分:2)

func addition = (func)GetProcAddress(loadedDLL, "addXYWrap");

GetProcAddress的此次调用会返回addXYWrap地址,而不是其值。由于addXYWrap是一个函数指针(与func的类型相同),这意味着它返回一个指向函数指针的指针,或func*

尝试将该行更改为:

func addition = *(func*)GetProcAddress(loadedDLL, "addXYWrap");

或者,或者:

func* addition = (func*)GetProcAddress(loadedDLL, "addXYWrap");

然后(*addition)(3, 4)

答案 1 :(得分:1)

所以,根据上面的评论,你似乎是在思考它。如果您需要一个函数指针,那么要正确调用它,您必须首先取消引用GetProcAddress,如下所示:

func addition = *(func*)GetProcAddress(loadedDLL, "addXYWrap");

但是,一个更方便的解决方案是将函数包装起来:

__declspec(dllexport) int myAddXY(int x, int y)
{
    return addXY(x, y);
}

答案 2 :(得分:-1)

version

这是一个错误。您必须导出函数,而不是全局指针。也就是说,

import sys
from PyQt5.QtCore import QObject, pyqtSlot
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebKitWidgets import QWebView

html = """
<html>
<body>
    <h1><button onmousedown="foo()">Push me!</button></h1>
</body>

<script>
    function foo() {
        if(penDetector.isPenUsed()){
            alert("Booya!");
        }
    }
</script>
</html>
"""


class TestView(QWebView):
    class PenDetector(QObject):
        def __init__(self, parent=None):
            super().__init__(parent)
            self.penUsed = False

        @pyqtSlot(result=bool)
        def isPenUsed(self):
            return self.penUsed

    def __init__(self, parent=None):
        super().__init__(parent)
        self.penDetector = self.PenDetector()
        self.page().mainFrame().addToJavaScriptWindowObject("penDetector", self.penDetector)

    def mousePressEvent(self, event):
        self.penDetector.penUsed = False
        super().mousePressEvent(event)

    def tabletEvent(self, event):
        self.penDetector.penUsed = True
        super().mousePressEvent(event)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    view = TestView()
    frame = view.page().mainFrame()
    view.setHtml(html)
    view.show()
    app.exec_()