简体   繁体   中英

PInvoke Calling C++ code in C# - ObjectPinning

I am trying to follow tutorial calling code from C++ into C#.

I followed the coding part correctly.

But when I run the code I get exception: System.DllNotFoundException: 'Unable to load DLL 'SampleNativeLib': The specified module could not be found. (Exception from HRESULT: 0x8007007E)'

I create C# library as simple application file. And C++ as dynamic .dll.

In the original tutorial (I also have full project file of it) in the C# project in the references there are no references to C++ .dll. I would like to ask how C++ is referenced to C#?

The code of C#

using System;
using System.Linq;
using System.Runtime.InteropServices;

namespace ObjectPinning {
    class Program {

        [DllImport("SampleNativeLib")]
        static extern int SetData([MarshalAs(UnmanagedType.LPArray)] int[] darray);

        [DllImport("SampleNativeLib")]
        static extern int DoCalc();

        static void Main(string[] args) {

            var data = Enumerable.Range(0, 10).Select(i => i + 1).ToArray();
            GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
            Console.WriteLine(SetData(data));
            Console.WriteLine(DoCalc());
            Console.ReadLine();
            GC.Collect();//Clean up any garbage object
            Console.WriteLine(DoCalc());
            handle.Free();

        }
    }
}

The code of C++:

// SampleNativeLib.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"

int* g_pData;

extern "C" __declspec(dllexport) int WINAPI DoCalc() {
    int sum = 0;
    for(int i = 0; i < 10; i++)
        sum += g_pData[i];
    return sum;
}

extern "C" __declspec(dllexport) int WINAPI SetData(int* data) {
    g_pData = data;
    return DoCalc();
}

My project file: Download

Teachers File: Download

My file 在此处输入图片说明

Teacher File 在此处输入图片说明

The exception you get is most likely because you didn't add the dll to the C# executable path. In the first step the application searching the dependencies in the exe directory, if not found, then it goes through the Window environment variables. That is why we don't need to copy the dlls when we use some of the Windows API function, because if you look at at your PATH variable, you'll have %SystemRoot% variable which links to your windows folder.
In C# you can't really reference C++ projects as you already know when adding another C# project, since you calling from managed code to unmanaged/native code.
Important note when you building your own C++ dll, make sure the compiler environment set to x32 bit, otherwise you'll get some other exceptions when calling C++ code from C#.
What actually expose the C++ function to allow for it consumed by other languages, is the:

extern "C" __declspec(dllexport) 

On the signature of the function. So that gives you the power to do almost everything you can do with C++ also in C#/Java.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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