[Mono-list] InteropServices: DllNotFoundException...?

Simon Ask Ulsnes simon@ulsnes.dk
Thu, 20 May 2004 23:47:21 +0200


This is a multi-part message in MIME format.
--------------060009090602090900010600
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hi there!
I'm trying to write a Mono wrapper for GPGME (GnuPG Made Easy, an 
application wrapper to GPG).
It's becoming wrapper around wrapper around wrapper, but what the 
heck... ;-)

Of course, I'm using InteropServices to interact with a C library. I 
made a few wrapper functions in the library, and the basic ones (such as 
checking the library version and such) work well. But after I added the 
latest (GetKeyNames and GetKeyXML), loading the library starts shouting 
Exceptions - namely DllNotFoundException. Yes, the library is in place.

I'm think I'm making a mistake in writing the C library part properly, 
but what exactly is it I'm doing wrong?

Attached is the source code, along with a small compile script I use for 
smaller test projects (simply chmod +x and run to compile).

Yours,
Simon


--------------060009090602090900010600
Content-Type: text/x-csharp;
 name="InterfaceTest.cs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="InterfaceTest.cs"

using System;
using System.Runtime.InteropServices;

namespace SecureStorage
{
	public class InterfaceTest
	{
		public static void Main(string[] args)
		{
			new InterfaceTest();
		}

		[DllImport("./libsecstor.so")] private static extern bool CheckEngine();
		[DllImport("./libsecstor.so")] private static extern string GetEngineInfoXML();
		[DllImport("./libsecstor.so")] private static extern string GetKeyNames();
		[DllImport("./libsecstor.so")] private static extern string GetKeyXML(string keyname);

		public InterfaceTest()
		{
			if (CheckEngine())
			{
				Console.WriteLine("Engine OK\n");
				
				string[] keys = GetKeyNames().Split(',');
				foreach (string s in keys)
				{
					Console.WriteLine(s);
				}
			}
			else
			{
				Console.WriteLine("Engine error...");
			}
		}
	}
}

--------------060009090602090900010600
Content-Type: text/plain;
 name="compile"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="compile"

#!/bin/sh
gcc -o libsecstor.so -shared `gpgme-config --cflags --libs` *.c
mcs -out:secstor.exe *.cs

--------------060009090602090900010600
Content-Type: text/x-csrc;
 name="gpg-interface.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="gpg-interface.c"

#include <gpgme.h>

#define bool int
#define true 1
#define false 0

extern bool CheckEngine()
{
	GpgmeError err;
	err = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
	if (err == GPGME_No_Error)
		return true;
	else
		return false;
}

extern char* GetEngineInfoXML()
{
	return (char*)gpgme_get_engine_info();
}

extern char* GetKeyNames()
{
	GpgmeCtx ctx;
	GpgmeError err = gpgme_new(&ctx);
	GpgmeKey key;
	
	char* ret = "";

	err = gpgme_op_keylist_start(ctx, "", 0);
	while (!err && (err = gpgme_op_keylist_next(ctx, &key)) != GPGME_EOF)
	{
		ret = strcat(ret, ",");
		ret = strcat(ret, (char*)gpgme_key_get_string_attr(key, GPGME_ATTR_KEYID, 0, 0));
		gpgme_release_key(key);
	}
	
	gpgme_release(ctx);

	return ret;
}

extern char* GetKeyXML(char* keyname)
{
	GpgmeCtx ctx;
	GpgmeError err = gpgme_new(&ctx);

	GpgmeKey key;
	
	if (!err)
	{
		err = gpgme_op_keylist_start(ctx, keyname, 0);
		while (!err && (err = gpgme_op_keylist_next(ctx, &key)) != GPGME_EOF)
		{
		}
		gpgme_release(ctx);
	}

	char* ret = gpgme_key_get_as_xml(key);
	gpgme_key_release(key);
	return ret;
}

--------------060009090602090900010600--