为 haskell 堆栈项目编写静态 cpp 库

Posted

技术标签:

【中文标题】为 haskell 堆栈项目编写静态 cpp 库【英文标题】:Writing a static cpp library for a haskell stack project 【发布时间】:2018-09-11 11:56:57 【问题描述】:

我正在尝试使用 haskell 堆栈为 Windows 编写调试器。因为没有其他方法可以使用haskell 包将正确的标志传递给CreateProcess,所以我决定为其编写一个包装器。这是我所做的:

// process.h
#pragma once

// Headers
#include <Windows.h>

// Functions
HANDLE CreateDebuggedProcess(LPCSTR lpApplicationName);

//process.cpp

#include <Windows.h>

#include "process.h"

HANDLE CreateDebuggedProcess(LPCSTR lpApplicationName)

    STARTUPINFO startup_info =  0 ;
    PROCESS_INFORMATION process_information =  0 ;

    startup_info.cb = sizeof(startup_info);

    if (!CreateProcessA(
        lpApplicationName,
        NULL,
        NULL,
        NULL,
        FALSE,
        DEBUG_ONLY_THIS_PROCESS,
        NULL,
        NULL,
        &startup_info,
        &process_information
    ))
    
        return INVALID_HANDLE_VALUE;
    

    return process_information.hProcess;

我编译到DebuggedProcess.lib 在 Haskell 项目中,我有:

-# LANGUAGE ForeignFunctionInterface #-

module Main where

import System.Win32.Types
import Foreign.C.String

main :: IO ()
main = do
    withCString "cmd.exe" c_CreateDebuggedProcess
    putStrLn "created process"

foreign import ccall "DebuggedProcess.lib CreateDebuggedProcess"
    c_CreateDebuggedProcess :: LPCSTR -> IO HANDLE

我已将.lib 文件添加到堆栈路径(已使用stack path --extra-include-dirs 验证)并添加了extra-libraries: [DebuggedProcess]

但我收到以下错误:

>stack build
Building all executables for `tape' once. After a successful build of all of them, only specified executables will be rebuilt.
tape-0.1.0.0: configure (lib + exe)
Configuring tape-0.1.0.0...
Cabal-simple_Z6RU0evB_2.2.0.1_ghc-8.4.3.exe: Missing dependencies on foreign
libraries:
* Missing (or bad) C libraries: DebuggedProcess, DebuggedProcess,
DebuggedProcess
This problem can usually be solved by installing the system packages that
provide these libraries (you may need the "-dev" versions). If the libraries
are already installed but in a non-standard location then you can use the
flags --extra-include-dirs= and --extra-lib-dirs= to specify where they are.If
the library files do exist, it may contain errors that are caught by the C
compiler at the preprocessing stage. In this case you can re-run configure
with the verbosity flag -v3 to see the error messages.


--  While building custom Setup.hs for package tape-0.1.0.0 using:
    C:\sr\setup-exe-cache\x86_64-windows\Cabal-simple_Z6RU0evB_2.2.0.1_ghc-8.4.3.exe --builddir=.stack-work\dist\7d103d30 configure --with-ghc=C:\Users\yotam\AppData\Local\Programs\stack\x86_64-windows\ghc-8.4.3\bin\ghc.EXE --with-ghc-pkg=C:\Users\yotam\AppData\Local\Programs\stack\x86_64-windows\ghc-8.4.3\bin\ghc-pkg.EXE --user --package-db=clear --package-db=global --package-db=C:\sr\snapshots\68fc3218\pkgdb --package-db=D:\tape\.stack-work\install\db7ce97c\pkgdb --libdir=D:\tape\.stack-work\install\db7ce97c\lib --bindir=D:\tape\.stack-work\install\db7ce97c\bin --datadir=D:\tape\.stack-work\install\db7ce97c\share --libexecdir=D:\tape\.stack-work\install\db7ce97c\libexec --sysconfdir=D:\tape\.stack-work\install\db7ce97c\etc --docdir=D:\tape\.stack-work\install\db7ce97c\doc\tape-0.1.0.0 --htmldir=D:\tape\.stack-work\install\db7ce97c\doc\tape-0.1.0.0 --haddockdir=D:\tape\.stack-work\install\db7ce97c\doc\tape-0.1.0.0 --dependency=Win32=Win32-2.6.1.0 --dependency=base=base-4.11.1.0 --extra-include-dirs=C:\Users\yotam\AppData\Local\Programs\stack\x86_64-windows\msys2-20180531\mingw64\include --extra-include-dirs=D:\tape\lib --extra-lib-dirs=C:\Users\yotam\AppData\Local\Programs\stack\x86_64-windows\msys2-20180531\mingw64\bin --extra-lib-dirs=C:\Users\yotam\AppData\Local\Programs\stack\x86_64-windows\msys2-20180531\mingw64\lib --enable-tests --enable-benchmarks
    Process exited with code: ExitFailure 1

我不知道如何解决这个问题。任何帮助将不胜感激

【问题讨论】:

我会在导出的函数周围以extern "C" 开头。名称修改可能是问题的根源 【参考方案1】:

只需在您的.cabal 文件中使用c-sources: 即可使您的“库”静态编译成Haskell 可执行文件。示例如下:https://github.com/commercialhaskell/stack/pull/4238/files

【讨论】:

以上是关于为 haskell 堆栈项目编写静态 cpp 库的主要内容,如果未能解决你的问题,请参考以下文章

是否应该从 C++ 中的静态库项目中删除 stdafx.h/.cpp? [关闭]

怎么用C语言编写堆栈并能进行四则运算

Qt下如何编译库

cpp dll中c静态库的功能

使用 haskell 摇动构建工具。使用本地静态 c 库

动态库与静态库的区别在windows及linux环境下的制作及用法