简体   繁体   English

使用GHC 64位构建的普通Windows DLL无法链接

[英]Trivial Windows DLL built with GHC 64-bit does not link

For a proof-of-concept, I want to link some trivial Haskell code into my Visual C++ application (using Visual Studio 2013). 为了进行概念验证,我想将一些琐碎的Haskell代码链接到我的Visual C ++应用程序中(使用Visual Studio 2013)。 Building with GHC 7.8.3 32-bit works, but building with GHC 7.8.4 64-bit does not (notice the slight discrepancy in GHC version too). 使用GHC 7.8.3 32位版本进行构建,但是使用GHC 7.8.4 64位版本进行构建(请注意,GHC版本中也存在细微差异)。

There are 3 files: Grep.hs and StartEnd.c are built with GHC to form a DLL. 有3个文件: Grep.hsStartEnd.c与GHC一起构建以形成DLL。 main.cpp is built with Visual Studio 2013 and attempts to link in the DLL library. main.cpp与Visual Studio 2013一起构建,并尝试在DLL库中进行链接。

I am building the DLL from this: 我正在从中构建DLL:

> ghc -shared -O -optc-O -o Grep.dll StartEnd.c Grep.hs

And from within Visual Studio, I simply link against Grep.dll.a and include C:\\Program Files\\MinGHC-7.8.4\\ghc-7.8.4\\lib\\include , but linking fails with 从Visual Studio中,我只是链接到Grep.dll.a并包含C:\\Program Files\\MinGHC-7.8.4\\ghc-7.8.4\\lib\\include ,但是链接失败

1>main.obj : error LNK2001: unresolved external symbol _HsEnd
1>main.obj : error LNK2001: unresolved external symbol _freegrep
1>main.obj : error LNK2001: unresolved external symbol _grep
1>main.obj : error LNK2001: unresolved external symbol _HsStart
1>C:\Code\Grep\dist\Win32\Release\Grep.exe : fatal error LNK1120: 4 unresolved externals

The exact same process works when I build with 32-bit, but not 64-bit. 当我使用32位而不是64位进行构建时,完全相同的过程起作用。 What could I be doing wrong? 我可能做错了什么? (I am building a 64-bit app when attempting to link the 64-bit library.) (尝试链接64位库时,我正在构建64位应用程序。)

Source files: 源文件:

Grep.hs Grep.hs

{-# LANGUAGE ForeignFunctionInterface #-}

module Grep where

import Foreign
import Foreign.C.String
import Data.List (isInfixOf)

filterlines f = unlines . filter f . lines

grep :: CString -> CString -> IO CString
grep i s = do
    ii <- peekCString i
    ss <- peekCString s
    newCString $ (filterlines (isInfixOf ii)) ss

freegrep :: CString -> IO ()
freegrep s = free s

foreign export ccall grep :: CString -> CString -> IO CString
foreign export ccall freegrep :: CString -> IO ()

StartEnd.c StartEnd.c

#include <Rts.h>

void HsStart()
{
   int argc = 1;
   char* argv[] = {"ghcDll", NULL}; // argv must end with NULL

   // Initialize Haskell runtime
   char** args = argv;
   hs_init(&argc, &args);
}

void HsEnd()
{
   hs_exit();
}

main.cpp main.cpp中

#include <HsFFI.h>
#include <Grep_stub.h>
#include <iostream>

extern "C" {
    void HsStart();
    void HsEnd();
}

int main(int argc, char* argv[])
{
    HsStart();
    HsPtr str;

    str = grep("test", "This is a test\nwith many lines\nand it failed\nand the test passed");
    if (str)
    {
        std::cout << (char*) str;
        freegrep(str);
    }

    HsEnd();
    return 0;
}

Thanks to the comments, I added the actual error output to the post. 多亏了这些评论,我将实际的错误输出添加到了帖子中。 This caused me to notice that Visual Studio's confusing configuration management interface had bit me once again. 这使我注意到Visual Studio令人困惑的配置管理界面再次让我难过。 It was still trying to build the Win32 version even though my configuration setting said x64 . 即使我的配置设置为x64它仍在尝试构建Win32版本。 Long story short, it's working! 长话短说,它正在工作!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM