无法在 Visual C# 项目中使用我的 .dll

Posted

技术标签:

【中文标题】无法在 Visual C# 项目中使用我的 .dll【英文标题】:Unable to use my .dll in Visual C# project 【发布时间】:2015-03-22 18:38:33 【问题描述】:

我在 Visual Studio 2013 中创建了一个 DLL,它构建得很好。这是一个 Visual C++ 项目,但用 C 编写。但是,我无法添加我构建的 .dll 作为对我的 C# 项目的引用。我明白了:

A reference to 'C:\...\FileGuidUtils.dll' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.

我在网上学习了很多不同的教程,结果都一样。 The only MSDN tutorial我发现不考虑C代码,只考虑C++。

这是我的 FileGuidUtils.cpp 文件:

#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <ole2.h>
#include <errno.h>

extern "C" __declspec(dllexport) WCHAR* getFileIdFromPath(_TCHAR* path);
extern "C" __declspec(dllexport) WCHAR* getPathFromFileId(_TCHAR* guid);

__declspec(dllexport) WCHAR* getFileIdFromPath(_TCHAR* path) 
    HANDLE hFile;
    FILE_OBJECTID_BUFFER buf;
    DWORD cbOut;
    GUID guid;
    WCHAR *szGuid = (WCHAR *)malloc(sizeof(WCHAR) * 39);
    BOOL result;

    hFile = ::CreateFile(path, 0,
        FILE_SHARE_READ |
        FILE_SHARE_WRITE |
        FILE_SHARE_DELETE,
        NULL,
        OPEN_EXISTING,
        0, NULL);
    if (hFile == INVALID_HANDLE_VALUE) 
        fprintf(stderr, "CreateFile() Error: 0x%0.8x\n", ::GetLastError());
        ::CloseHandle(hFile);
        return NULL;
    
    result = ::DeviceIoControl(hFile,
        FSCTL_CREATE_OR_GET_OBJECT_ID,
        NULL, 0,
        &buf, sizeof(buf),
        &cbOut, NULL);
    if (!result) 
        fprintf(stderr, "DeviceIoControl() Error: 0x%0.8x\n", ::GetLastError());
        ::CloseHandle(hFile);
        return NULL;
    

    ::CopyMemory(&guid, &buf.ObjectId, sizeof(GUID));
    ::StringFromGUID2(guid, szGuid, 39);

    return szGuid;


__declspec(dllexport) WCHAR* getPathFromFileId(_TCHAR* guid) 
    struct FILE_NAME_INFO_AND_BUF 
        FILE_NAME_INFO fni;
        TCHAR buf[260];
    ;
    HANDLE hRoot;
    FILE_ID_DESCRIPTOR desc;
    HANDLE hFile;
    FILE_NAME_INFO_AND_BUF fnib =  0 ;
    HRESULT hr;
    TCHAR szRoot[] = _T("C:");
    BOOL result;

    hRoot = ::CreateFile(szRoot, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (hRoot == INVALID_HANDLE_VALUE) 
        _tprintf(_T("CreateFile() Error: 0x%0.8x\n"),
            ::GetLastError());
        return NULL;
    

    desc.dwSize = sizeof(desc);
    desc.Type = ObjectIdType;

    hr = ::CLSIDFromString(guid, &desc.ObjectId);
    if (FAILED(hr)) 
        fprintf(stderr, "CLSIDFromString() Error: 0x%0.8x\n", ::GetLastError());
        ::CloseHandle(hRoot);
        return NULL;
    

    hFile = ::OpenFileById(hRoot, &desc, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 0);
    if (hFile == INVALID_HANDLE_VALUE) 
        fprintf(stderr, "OpenFileById() Error: 0x%0.8x\n", ::GetLastError());
        ::CloseHandle(hFile);
        return NULL;
    

    result = ::GetFileInformationByHandleEx(hFile, FileNameInfo, &fnib, sizeof(fnib));
    if (!result) 
        fprintf(stderr, "GetFileInformationByHandleEx Error %d\n", ::GetLastError());
        ::CloseHandle(hFile);
        return NULL;
    

    wchar_t *path = (wchar_t *)malloc(sizeof(wchar_t) * 512);
    wcscpy_s(path, 256, szRoot);
    wcscat_s(path, 256, fnib.fni.FileName);

    return path;

还有其他自动生成的文件,但我没有修改它们,除了注释掉 stdafx.h 中的 #define WIN32_LEAN_AND_MEAN 行,因为我的项目需要完整版本的 Windows.h。

【问题讨论】:

【参考方案1】:

并且它是一个有效的程序集或 COM 组件

两者都不是。您必须在 C# 项目中编写 [DllImport] 声明才能使用它。

如果您希望添加引用起作用,那么最简单的方法是使用public ref class 创建一个 C++/CLI 项目。文件 > 添加 > 新项目 > Visual C++ > CLR > 类库模板。需要对 C++/CLI 语法有最少的了解才能顺利完成。

【讨论】:

以上是关于无法在 Visual C# 项目中使用我的 .dll的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Visual Studio 中创建独立的 exe? [复制]

表单视图设计器无法在 Visual Studio 2019 中使用 c# .NET Core 3.1 [重复]

如何在我的 C# Visual Studio 项目中添加 VC++ DLL 作为引用?

无法在 Visual Studio 2010 c# 中使用 SoundPlayer 播放声音

Visual Studio 2008 中的 C# 项目中的 C++ 项目参考

使用 Visual Studio 2012 Profiler 分析 C++