Getting error " Attempted to read or write protected memory"
This is what is in the header file.
/// Creates a new file geodatabase in the specified location.
/// @param[in] path The location where the geodatabase should be created.
/// @param[out] geodatabase A reference to the newly-created geodatabase.
/// @return A long integer indicating whether the method finished successfully.
EXT_FILEGDB_API long CreateGeodatabase(const std::wstring& pat开发者_开发知识库h, Geodatabase& geodatabase);
This is what my dllimport looks like.
[DllImport("FileGDBAPI.dll", EntryPoint = "#49", SetLastError=true, CallingConvention=CallingConvention.Winapi)]
public static extern int CreateGeodatabase([MarshalAs(UnmanagedType.LPStr)]string path, ref IntPtr geodatabase);
..and this is the code thats using it.
IntPtr Geodatabase = IntPtr.Zero;
FileGDBAPI_wrapper.CreateGeodatabase("c:\temp\testGDB.gdb", ref Geodatabase);
What am I doing wrong?
I see two possible problems:
- The C++ code is using a wide string, the C# code an ANSI string
- The C++ code is using the
std::wstring
class, and not a c style null terminated string
I don't think you can fix the second problem easily without changing the API on the C++ side
If you are using .NET 4.0, try passing parameters without the ref
keyword.
i.e.
FileGDBAPI_wrapper.CreateGeodatabase("c:\temp\testGDB.gdb", /ref/ Geodatabase);
and let me know if this works for you.
EDIT
Forget about my previous answer, I was typically ignorant.
I think you need to mark the Geodatabase
as out
instead of ref
in both the declaration and invocation of the function; in this case you will NOT need to initialize your IntPtr before passing it to CreateGeodatabase()
I guess -and may be I am still ignorant - the problem related to declaring the Geodatabase argument in your library as a reference not as a pointer, that is, you can't pass null (IntPtr.Zero) to it, and typically, you don't need so, you need it as an out parameter.
maybe this is useful
void MarshalString ( String ^ s, wstring& os ) {
using namespace Runtime::InteropServices;
const wchar_t* chars =
(const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
精彩评论