@@ -61,18 +61,7 @@ static object GetDelegate(INativeLibImporter importer, IntPtr lib, string entryP
6161 {
6262 IntPtr procAddress = importer . GetProcAddress ( lib , entryPoint ) ;
6363 if ( procAddress == IntPtr . Zero )
64- {
65- var invokeMethod = delegateType . GetTypeInfo ( ) . GetMethod ( "Invoke" ) ;
66- var parameters = invokeMethod . GetParameters ( ) . Select ( p => Expression . Parameter ( p . ParameterType ) ) . ToArray ( ) ;
67- var returnType = invokeMethod . ReturnType ;
68- var errorMessage = string . Format ( "Unable to get address of {0} ({1})" , entryPoint , delegateType ) ;
69- Action throwAction = ( ) => throw new NativeLoadException ( errorMessage , null ) ;
70- var callThrowExpr = Expression . Constant ( throwAction , typeof ( Action ) ) ;
71- var defaultExpr = Expression . Default ( returnType ) ;
72- var block = Expression . Block ( returnType , Expression . Invoke ( callThrowExpr ) , defaultExpr ) ;
73- var lambda = Expression . Lambda ( delegateType , block , parameters ) ;
74- return lambda . Compile ( ) ;
75- }
64+ return null ;
7665 var method = typeof ( CurrentFramework ) . GetTypeInfo ( ) . GetMethod ( nameof ( CurrentFramework . GetDelegateForFunctionPointer ) ) . MakeGenericMethod ( delegateType ) ;
7766 return method . Invoke ( null , new object [ ] { procAddress } ) ;
7867 }
@@ -240,7 +229,7 @@ public static T Import<T>(INativeLibImporter importer, string libName, string ve
240229 MethodInfo = m ,
241230 DelegateType = delegateMap [ GetMethodSig ( m ) ] ,
242231 } ) . ToArray ( ) ;
243- var fields = delegates . Select ( ( d , i ) => typeBuilder . DefineField ( $ "{ d . MethodInfo . Name } _func_{ i } ", d . DelegateType , FieldAttributes . Private ) ) . ToArray ( ) ;
232+ var delegateFields = delegates . Select ( ( d , i ) => typeBuilder . DefineField ( $ "{ d . MethodInfo . Name } _func_{ i } ", d . DelegateType , FieldAttributes . Private ) ) . ToArray ( ) ;
244233
245234 // Create the constructor which will initialize the importer and library handle
246235 // and also use the importer to populate each of the delegate fields
@@ -266,7 +255,7 @@ public static T Import<T>(INativeLibImporter importer, string libName, string ve
266255
267256 var getDelegateMethod = typeof ( INativeLibImporter ) . GetTypeInfo ( ) . GetMethod ( "GetDelegate" ) ;
268257 // Initialize each delegate field
269- for ( int i = 0 ; i < fields . Length ; i ++ )
258+ for ( int i = 0 ; i < delegateFields . Length ; i ++ )
270259 {
271260 var delegateType = delegates [ i ] . DelegateType ;
272261
@@ -280,7 +269,7 @@ public static T Import<T>(INativeLibImporter importer, string libName, string ve
280269 il . Emit ( OpCodes . Call , typeof ( System . Type ) . GetTypeInfo ( ) . GetMethod ( "GetTypeFromHandle" ) ) ; // typeof()
281270 il . Emit ( OpCodes . Callvirt , getDelegateMethod ) ; // importer.GetDelegate()
282271 il . Emit ( OpCodes . Isinst , delegateType ) ; // as <delegate type>
283- il . Emit ( OpCodes . Stfld , fields [ i ] ) ;
272+ il . Emit ( OpCodes . Stfld , delegateFields [ i ] ) ;
284273 }
285274
286275 // End of constructor
@@ -313,21 +302,25 @@ public static T Import<T>(INativeLibImporter importer, string libName, string ve
313302 il . Emit ( OpCodes . Ret ) ;
314303 }
315304
305+ var nativeFunctionMissingExceptionConstructor = typeof ( NativeFunctionMissingException ) . GetTypeInfo ( ) . GetConstructor ( new [ ] { typeof ( string ) } ) ;
316306 // Now override each method from the base class
317- for ( int i = 0 ; i < fields . Length ; i ++ )
307+ for ( int i = 0 ; i < delegateFields . Length ; i ++ )
318308 {
319309 var baseMethod = delegates [ i ] . MethodInfo ;
320310 var args = baseMethod . GetParameters ( ) ;
321311 var omethod = typeBuilder . DefineMethod (
322- baseMethod . Name ,
323- ( baseMethod . Attributes & ~ ( MethodAttributes . Abstract | MethodAttributes . NewSlot ) ) | MethodAttributes . Virtual ,
324- baseMethod . CallingConvention ,
325- baseMethod . ReturnType ,
312+ baseMethod . Name ,
313+ ( baseMethod . Attributes & ~ ( MethodAttributes . Abstract | MethodAttributes . NewSlot ) ) | MethodAttributes . Virtual ,
314+ baseMethod . CallingConvention ,
315+ baseMethod . ReturnType ,
326316 args . Select ( arg => arg . ParameterType ) . ToArray ( )
327317 ) ;
328318 var il = omethod . GetILGenerator ( ) ;
329319 il . Emit ( OpCodes . Ldarg_0 ) ; // this
330- il . Emit ( OpCodes . Ldfld , fields [ i ] ) ; // {field}
320+ il . Emit ( OpCodes . Ldfld , delegateFields [ i ] ) ; // {field}
321+ il . Emit ( OpCodes . Dup ) ;
322+ var error = il . DefineLabel ( ) ;
323+ il . Emit ( OpCodes . Brfalse_S , error ) ;
331324 if ( args . Length >= 1 )
332325 il . Emit ( OpCodes . Ldarg_1 ) ;
333326 if ( args . Length >= 2 )
@@ -339,6 +332,10 @@ public static T Import<T>(INativeLibImporter importer, string libName, string ve
339332 il . Emit ( OpCodes . Tailcall ) ;
340333 il . Emit ( OpCodes . Callvirt , delegates [ i ] . DelegateType . GetTypeInfo ( ) . GetMethod ( "Invoke" ) ) ;
341334 il . Emit ( OpCodes . Ret ) ;
335+ il . MarkLabel ( error ) ;
336+ il . Emit ( OpCodes . Ldstr , baseMethod . ToString ( ) ) ;
337+ il . Emit ( OpCodes . Newobj , nativeFunctionMissingExceptionConstructor ) ;
338+ il . Emit ( OpCodes . Throw ) ;
342339 }
343340
344341 var type = typeBuilder . CreateTypeInfo ( ) ;
@@ -453,6 +450,19 @@ private static TypeInfo CreateDelegateType(ModuleBuilder moduleBuilder, MethodIn
453450
454451 }
455452
453+ public class NativeFunctionMissingException : Exception
454+ {
455+ public NativeFunctionMissingException ( )
456+ : base ( "Failed to find entry point" )
457+ {
458+ }
459+
460+ public NativeFunctionMissingException ( string entryPoint )
461+ : base ( $ "Failed to find entry point for { entryPoint } ", null )
462+ {
463+ }
464+ }
465+
456466 public class NativeLoadException : Exception
457467 {
458468 public NativeLoadException ( string message , Exception inner )
0 commit comments