Trivial Windows DLL built with GHC 64

For a proof-of-concept, I want to link some trivial Haskell code into my Visual C++ application (using 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).

There are 3 files: Grep.hs and StartEnd.c are built with GHC to form a DLL. main.cpp is built with Visual Studio 2013 and attempts to link in the DLL library.

I am building the DLL from this:

> 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 FilesMinGHC-7.8.4ghc-7.8.4libinclude , but linking fails with

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:CodeGrepdistWin32ReleaseGrep.exe : fatal error LNK1120: 4 unresolved externals

The exact same process works when I build with 32-bit, but not 64-bit. What could I be doing wrong? (I am building a 64-bit app when attempting to link the 64-bit library.)

Source files:

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

#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

#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 testnwith many linesnand it failednand 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. It was still trying to build the Win32 version even though my configuration setting said x64 . Long story short, it's working!

链接地址: http://www.djcxy.com/p/33330.html

上一篇: 如何在windows 64上为ghc 7.10设置cabal

下一篇: 用GHC 64构建的简单Windows DLL